1

我想使用标准(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 端口。

你有什么想法?

此处不考虑接受其他连接并立即关闭它们的选项。

4

3 回答 3

1

只是在需要之前不要accept(2)建立新的连接。循环接受、处理客户端对话并关闭连接的套接字。

于 2012-12-10T18:36:31.313 回答
0

首先,尝试更改第二行代码(当前int MAXCONNECTIONS = 5;

于 2012-12-10T18:15:26.300 回答
0

首先,让我们区分监听套接字和连接套接字。监听套接字是服务器监听的套接字,即等待客户端。一旦调用accept返回,就意味着与客户端的3次握手完成并且accept返回一个连接的socket。连接的套接字是与客户端进行实际通信的套接字。

在您的示例中,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);
}

如果您想在处理一个请求时拒绝与其他连接的连接,您可能希望将 backlog 值减少到 1。但这不会向ECONNREFUSE客户端发送错误,而只会忽略客户端请求。但是,当服务器空闲时,即使这样,服务器队列中也只有一个连接。(不太清楚你为什么要这样做。)

于 2012-12-10T18:30:23.920 回答