单连接服务器套接字

时间:2012-12-10 18:12:39

标签: c++ sockets

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

你有什么想法吗?

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

3 个答案:

答案 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错误,但会忽略客户要求。但是,当服务器空闲时,即使这样,服务器在其队列中也只有一个连接。 (不太确定为什么你真的想要这样做。)