socket 怎么检测连接是不是断开?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket 怎么检测连接是不是断开?相关的知识,希望对你有一定的参考价值。

Windows下通过WSASend、WSARecv函数的返回值和错误代码判断,而者缺一不可!
iRet = WSARecv(pClient->m_Socket, &(pBuffer->m_WsaBuffer), 1, &liosize, &lFlags, &(pBuffer->m_Olp), NULL);
if(SOCKET_ERROR == iRet && ERROR_IO_PENDING != WSAGetLastError())

TRACE("ServerIoThread WSARecv call ClearClient: %d\r\n",pClient->m_Socket);
pThis->ClearClient(pClient,pBuffer);
参考技术A 使用send向对方发送数据,或者调用recv接收数据的时候,都可以判断是否已断开。

Web Socket:无法在 Internet 断开连接时检测到客户端连接

【中文标题】Web Socket:无法在 Internet 断开连接时检测到客户端连接【英文标题】:Web Socket: cannot detect client connection on internet disconnect 【发布时间】:2014-08-09 15:18:14 【问题描述】:

如果客户端使用 Web 套接字关闭互联网,我想检测客户端连接。我的代码是:

 //Include util library
    var util = require('util');
    // Include underscore library
    var _ = require('underscore')._;
    //For websocket
var webSocketServer = new (require('ws')).Server(port: (process.env.PORT || 5000)),
webSockets =  // userID: webSocket

// CONNECT /:userID
// wscat -c ws://localhost:5000/1
webSocketServer.on('connection', function (webSocket) 

  var userID = webSocket.upgradeReq.url.substr(1);
  //console.log('User_id is ',userID);
  webSockets[userID] = webSocket
                   util.log('User_id: [' + userID + '] enter in connected users list of [ ' + Object.getOwnPropertyNames(webSockets)+' ]')
                   // Call function which check id exist in letswalkee DB table
                   check_userid(userID);


                   // Send msg like: [fromUserID, text]    [1, "Hello, World!"]
webSocket.on('message', function(message) 
util.log('Received from [' + userID + ']: ' + message)
var messageArray = JSON.parse(message)
                                    var toUserWebSocket = webSockets[messageArray[0]]
                                    if (toUserWebSocket) 
                                    util.log('Sent to [' + messageArray[0] + ']: ' + JSON.stringify(messageArray))
                                    messageArray[0] = userID
                                    toUserWebSocket.send(JSON.stringify(messageArray))
                                    
                                    )

                   webSocket.on('close', function () 
                   
                      delete webSockets[userID]
                      util.log('User_id Deleted from connected users: [ ' + userID+' ]');

                    )
webSocket.on('disconnect',function()
  
   console.log('hello i am disconnected');  
  );
)

我使用了那个代码 (webSocket.on('disconnect',function()) 但没有用。

【问题讨论】:

【参考方案1】:

WebSocket 是基于 TCP 的,TCP 使用 FIN 包来关闭连接。在 Internet 连接突然丢失的情况下,WebSocket 服务器和电话都不会意识到 TCP 连接已经死掉,因为没有发送 FIN 数据包。

为了解决这个问题,TCP 有一个称为keepalive 的机制。

我为解决这个问题所做的是调整 Linux 内核中的 TCP keepalive 设置,并调用 ws._socket.setKeepAlive(true).

参考: https://github.com/websockets/ws/issues/353

【讨论】:

【参考方案2】:

对于基于 TCP 的协议(例如 Websockets),通常所做的是在应用层来回发送心跳/ping 数据包,以便每一方都可以轻松/快速地确定连接是否由于某种原因而消失。

【讨论】:

我将那个 socket 火箭服务器用于我的 iOS 本机应用程序。因此,当客户端关闭互联网时,服务器无法删除该客户端的连接。请告诉如何关闭该连接? 像我上面提到的那样,每隔一段时间从两端发送心跳/ping数据包,您可以检测到死连接。

以上是关于socket 怎么检测连接是不是断开?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 socket.io 上的断开连接?

Socket服务器端如何检测客户端的连接状态?

使用 Socket.io 检测(客户端)连接断开

C#socket通信时,怎样判断socket双方是不是断开连接

如何判断socket客户端连接断开

如何用C语言检测网络是不是连接上、已连接、已断开状态