TCP是半关闭的,我在客户端使用以下方法关闭:
shutdown(sock, SD_BOTH);
closesocket(sock);
期望的是服务端连接也主动关闭,不再调用一次关闭操作。
但从状态上看客户端一直处理在FIN_WAIT_2状态,服务端处在CLOSE_WAIT状态。
监控报文的确是只有客户端发送了FIN/ACK。
如何才能只在客户端调用一次关闭就能关闭两个方向的连接呢?

解决方案 »

  1.   

    shutdown(sock, SD_BOTH); 去掉.closesocket(sock); 直接用.
      

  2.   

    两边肯定都要调用closesocket你这边close是不可能把对方的资源释放掉,如果你不调用,只能等超时系统自己释放
      

  3.   

    顶楼上shutdown(sock, SD_BOTH); 关闭双方连接. closesocket(sock); 清除本地资源.
      

  4.   

    考虑到双方关闭连接时要回收资源或清理资源,建议用closesocket,当然在服务端要做的工作更多,特别是客户端非正常关闭或网络不明断开,都要处理,这样的程序才会健壮
      

  5.   

    closesocket 直接关闭就可以 服务器端可以根据客户端状态(比如断了,速率非常小)做些处理再关。
      

  6.   

    一方断了就是关闭了连接,客户端不可能帮服务器清资源的,因此还是需要服务器端自己调用closesocket和做善后工作..............
      

  7.   

    closesocket(socket)。
    应该没有其它事情处理吧(服务器端)?!
      

  8.   


    因为在关闭前socket还有没传输完的数据。
    方法1:完美关闭
    A.保证socket中已经没有数据需要接收(可以peek一下socket是否还有数据存在系统缓冲),如果还有数据,先接完,然后用shutdown(),再使用closesocket(),如果没数据了,还是一样。方法2:强硬关闭
    setsockopt()设置SO_LINGER去关闭,这样做就是在closesocket()时如果socket缓冲还残留有数据也会忽略,直接释放掉socket
      

  9.   

    永远不要用自己的逻辑正确来保证对端的逻辑正确,双方都closesocket还有可能有问题了,何况对方不close?
      

  10.   

    要说强硬关闭,我测试好像并没有强硬关闭
    例如我有一段程序,经测试并没有关闭,程序运行知道本身死掉(机器没有死掉):
         lig.l_onoff=0;  
         lig.l_linger=0;  
         iLen=sizeof(struct linger);  
         setsockopt(GPRS_SOCKETS[j].sockid,SOL_SOCKET,SO_LINGER,(char *)&lig,iLen);  
         closesocket(GPRS_SOCKETS[j].sockid); 
      

  11.   

    要说强硬关闭,我测试好像并没有强硬关闭
    例如我有一段程序,经测试并没有关闭,程序运行直到本身死掉(机器没有死掉):
        lig.l_onoff=0; 
        lig.l_linger=0; 
        iLen=sizeof(struct linger); 
        setsockopt(GPRS_SOCKETS[j].sockid,SOL_SOCKET,SO_LINGER,(char *)&lig,iLen); 
        closesocket(GPRS_SOCKETS[j].sockid); 
      

  12.   

    服务端设置强制关闭要在每次accept之前
      

  13.   

    不明白你的意思?
    假如我要创建一个线程监控每个socket,发现有一定时间没有通讯,我就要强制关闭该socket.
    怎么能在accept之前关闭??
      

  14.   

    是我没说清楚,准确讲是在"accept的时候"设置,每次accept不是都accept出来一个新的socket嘛,就在accept下面一句写设置就好了
      

  15.   

    感谢你的回答!
    但是我还是不太明白:为什么要在accept后关闭?还有,假如我采用的是WSAAsyncSelect模型,那么accept是在 case FD_ACCEPT分支中建立socket连接,在该分支中,如何判断要关闭哪一个socket?也就是说,已经有多个socket,如何判断出要关闭某个长时间没有通讯的socket?
      

  16.   

    不是accept之后关闭,只是设置下关闭属性,到closesocket的时候自动生效。
    关于如何判断长时间没有通讯的socket,要上层自己做心跳检测,socket有keep-alive属性可以设置,但是不建议使用,心跳机制是tcp程序所必须的
      

  17.   

    不是很同意楼上的说法,我记得我当初是这样做的:shutdown(sock, SD_BOTH); //关闭双向连接//!重要,延时一下
    Sleep(800);closesocket(sock); //关闭 套接
      

  18.   

    再帖一次。 //慢速网络应这样做:Shutdown、延时、closesocket
    //将发送FIN,以关闭连接
    shutdown(client, 1);
    Sleep(600); //适当延时
    closesocket(client);
    //中止Windows Sockets DLL的使用
    WSACleanup();
      

  19.   

    使用shutdown的时候,可以循环读取缓冲区,直到缓冲区全部读取完毕再关闭。采用sleep延迟的方式永远不是太好的方式,你能保证这段时间到底多长吗?
    还有好像有点跑题了,我在上面说的设置linger也只是为了防止出现close_wait,并且据我理解,做了shutdown以后linger设置就无意义了,因为设置linger为0的目的就是为了不发FIN而直接RESET.
    呵呵,我现在也不知道楼主想问的是什么了。
      

  20.   

    呵呵,补充一句,我上面说的是shutdown掉写操作,因为你对数据的完整性无要求,当然可以连读也shutdown掉,不过还是不要用Sleep这么用。