First of all , Server's socekt is not close.
if u had closed client's socekt , u should creat it again when u want to connect server's.
socket即使close了,也还是会存在的,除非设置socket的option,设置为立即close
看一下setsockopt()这个函数吧
附一朋友的问题:
服务器程序为Socket Sever,绑定12005端口,启动就Listen,然后客户端不停的连接、断开,在每天4点服务器程序自动关闭后,又由另外一个守候程序打开。服务器运行8-9天后,客户端不能连接了,连接的客户端也请求不了数据,就是说服务器程序不接受SOCKET连接了,发送的数据在OnReceive()不能接受了,在这个时间用远程登录可以登录到服务器,CPU也是4%左右,自己的服务器程序用内存也是不到10M(曾经到过70M也没问题),数据的一条线城也没有堵塞(当时自己打开SQL2000企业管理器查看到的),关闭自己服务器程序,客户端又可以连接上来,但是过了2个小时又是上面的情况,这次关闭自己服务器程序也不能连接了,只好将操作系统关闭,重新启动服务器机器,重起后可以了。
又要运行到8-9天后才发生重复的事情、、、,好奇怪呀,已经连续发生4次了,找不到原因,
自己认为
1、是不是操作系统的端口8-9天后用完了?如果是
2、内存用完了?(1G系统内存,在资源管理器看到是一直稳定到830M左右)
---------------------------------------------------------------------------------------------------
TCP连接如果不收发数据,大约几十秒之后就会超时,超时之后服务器端不会收到OnClose()
这样一来,就会有许多死连接,服务器端无法清除。
b/S之间没有数据发送的时候要发送一些在线包,比如说,没有数据传输时每20秒发送一个空格
Server端对每个连接定时检测,大概象下面这样:
OnRecv()
{
last_recv_time = GetTickCount();
//do recv() here
}
OnTimer()
{
if(GetTickCount()-last_recv_time>35000)//close connection any way after 35 seconds' idle
{
closesocket(s)
}
}
客户端要有重连机制
C#中判断socket是否已断开的方法
在C#中,Socket类的Connected属性只表示最后一次I/O操作的状态,如果这之后[连接的另一方]断开了,它还一直返回true, 除非你再通过socket来发送数据。所以通过这个属性来判断是行不通的!
有人说可以用Socket.Available属性来判断,msdn中说:如果[连接的另一方]断开了,它就会抛出异常。然而,这个BUG报告(http://dam.mellis.org/2004/08/net_socket_bugs_gotchas/)却指出:msdn的说法并不完全正确,这个属性只有在少数情况下才抛出异常。所以,这一招还是行不通!
事实上,Socket.Receive()方法在[连接的另一方]断开时,它返回结果告知只读了0个字节,我们可以籍由这一点来找出答案。这个问答(http://www.dotnet247.com/247reference/msgs/36/182526.aspx)给出了好的解决方案:可以调用Socket.Poll() 方法,为该方法的第二个参数传入SelectRead 值,如果该方法返回true, 则可以再由Socket.Receive()方法的返回值来判断, 我简要的写出代码:
Socket s = new Socket(..);
if (s.Poll(-1, SelectMode.SelectRead))
{
int nRead = s.Receive();
if (nRead == 0)
{
//socket连接已断开
}
}
如果您还有更好的方法,也请告诉我, :).