2013-06-12 28 views
-2

我正在实现一个服务器,在该服务器中,我侦听客户端使用accept套接字调用进行连接。套接字呼叫之间的时间差距,即。 Accept()和recv/send calls

接受发生后,我收到套接字,我等待大约10-15秒,然后再进行第一次recv /发送呼叫。

发送到客户端的呼叫失败,errno = 32,即断开管道。

由于我不控制客户端,我在接受的套接字中设置了套接字选项* SO_KEEPALIVE *。

const int keepAlive = 1; 
acceptsock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_length) 
if (setsockopt(acceptsock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) < 0) 
{ 
    print(" SO_KEEPALIVE fails"); 
} 

任何人都可以请告诉可能会出现什么问题,以及我们如何防止客户端套接字关闭?

注意 ,我想在这里补充一点的是,如果没有时间间隔或接受和发送/ recv的调用之间小于5秒,按预期发生在客户端服务器通信。

+0

在Linux中,你可以得到errno = 32的错误:ENOTCONN也意味着 套接字没有连接,并且没有给出目标。请看你在发起send/recv之前所做的系统调用是不是返回错误 – Aravind

+1

在你开始调用send()之前,你确认了connect()实际上是否成功,并且通知你一个完整的连接可用?套接字在空闲时间后通常不会自行关闭,对于'SO_KEEPALIVE'来说,10-15秒的时间太短而无法关闭死连接,而10-15秒对于外部防火墙/路由器而言太短以至于无法关闭空闲连接。所以其他事情正在发生。我的猜测是你没有正确管理你的客户端套接字。 –

+0

@Aravind和Remy ..是的,connect()成功了,因为接受阻塞的调用给出了一个有效的accpetsock。此外,在我开始收到错误32之前,客户端也会收到两次或三次数据。正如我已经提到,如果在接受和发送/接收呼叫之间没有等待,我不拥有客户端和客户端的工作。 – Rajat

回答

0

connect(2)send(2)是客户端进行的两个独立的系统调用。第一个启动TCP three-way handshake,第二个实际排队传输的应用程序数据。

在服务器端虽然,你能完成后立即启动send(2) -ing数据连接的插座成功accept(2)(即不要忘记检查acceptsock-1)。

+0

我想你不明白我的问题。谢谢澄清。请再次通过它。我正在执行对-1的检查,因为套接字是有效的。 – Rajat

+0

你必须解释实际问题是什么。添加更多信息,比如什么应用程序级别的协议用于套接字,以及您认为应该发生什么。 –

0

After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.

为什么?你的意思是客户需要很长时间才能发送数据?或者你只是在服务器上寻找accept()recv()之间10-15秒,如果是的话,为什么?

The send calls to the client fails with errno = 32 i.e broken pipe.

因此客户端已关闭连接。

Since I don't control the client, i have set socket option SO_KEEPALIVE in the accepted socket.

这不会阻止客户端关闭连接。

Could anyone please tell what may be going wrong here

客户端正在关闭连接。

and how can we prevent the client socket from closing ?

你不行。

+0

总之你想说的是在这里没有什么可以做的。我在等待,因为有一些数据需要处理并发送给客户端。所以没有别的选择,只能在发送数据给客户端之前等待这些数据。 – Rajat

+0

@Rajat'总之'我已经说过了,用我选择的话说:'你不能'。不要告诉我我想说什么。我对这种事情极度过敏。我已经说过我想说什么了,我不需要任何解释。我注意到你没有回答我的任何问题。 – EJP