我想使用标准(socket.h)库实现服务器c ++服务器程序(在linux下),该库只接受一个活动连接。我对如何实现这一点的理解是这样的(我已经删除了错误检查):
int port = 4711;
int MAXCONNECTIONS = 5;
int m_sock;
m_sock = socket ( AF_INET, SOCK_STREAM, 0 );
int on = 1;
setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof ( on ) ) < 0
sockaddr_in m_addr;
m_addr.sin_family = AF_INET;
m_addr.sin_addr.s_addr = INADDR_ANY;
m_addr.sin_port = htons ( port );
bind ( m_sock, ( struct sockaddr * ) &m_addr,
sizeof ( m_addr ) );
listen ( m_sock, MAXCONNECTIONS );
// now accept new connection and get socket
int con_sock;
int addr_length = sizeof ( m_addr );
con_sock = accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
这在我的代码中到目前为止有效。但是创建的第一个套接字仍然会接受连接。据我所知,我现在需要关闭第一个插座。
close ( m_sock );
这可以防止新连接。但是现在,当第一个连接爆炸时,我无法重新建立任何连接。从我的理解,我将不得不重复与上述相同的行为。
我遇到的是我的代码运行良好,直到它将阻止并等待连接,但客户端连接将收到“连接被拒绝”,我在netstat中看不到任何LISTEN端口。
你有什么想法吗?
接受其他连接并立即关闭它们的选项在此不予考虑。
答案 0 :(得分:1)
在您需要之前,不要accept(2)
新的连接。循环接受,处理客户端对话,并关闭连接的套接字。
答案 1 :(得分:0)
首先,尝试更改第二行代码(目前为int MAXCONNECTIONS = 5;
)
答案 2 :(得分:0)
首先,让我们区分监听套接字和连接的套接字。侦听套接字是服务器侦听的套接字,即等待客户端。一旦对accept的调用返回,则意味着与客户端的3次握手完成,并且accept返回连接的套接字。连接套接字是与客户端进行实际通信的套接字。
在您的示例中,m_sock
是一个侦听套接字,con_sock
是连接的套接字。当您关闭'm_sock'时,您实际上正在关闭侦听套接字,因此服务器无法再接受连接,这就是客户端连接拒绝错误的原因。
如果一次只处理一个请求是你的任务,我想你需要的是一个迭代服务器。您不需要关闭侦听套接字,因为只有在完成上一个请求完成后才会处理下一个请求。
listen ( m_sock, MAXCONNECTIONS );
// now accept new connection and get socket
int con_sock;
int addr_length = sizeof ( m_addr );
for(;;)
{
con_sock = accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
//do your task
close(con_sock);
}
如果要在处理一个请求时拒绝与其他连接的连接,您可能希望将积压值减少到1.但是这不会向客户端发送ECONNREFUSE
错误,但会忽略客户要求。但是,当服务器空闲时,即使这样,服务器在其队列中也只有一个连接。 (不太确定为什么你真的想要这样做。)