如何判断SOCKET还是连接着的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何判断SOCKET还是连接着的相关的知识,希望对你有一定的参考价值。

参考技术A // 判断是否连接

char ch = 'A';

if (read(g_sockfd, &ch, 1)<=0)



if (connect(g_sockfd,(struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr) ) == 0)



ServiceLog.write_log("[NotifyDAU]:connect to DAU success.");



else



ServiceLog.write_log("[NotifyDAU]:can't connect to DAU ");

return;





用trycatch是比较合适。

当他是连着的,当进行通讯时发生异常后就知道了.

当你不断的read的时候,server断,exception就catch到了。

2. 心跳包

可不可以在Client设一个定时器,每隔一段时间发一条消息给服务器,看能不能收到服务器的响应。

心跳包就是定时发包,没回应就判断断开。

3. getsockopt

int optval, optlen = sizeof(int);

getsockopt(sd, SOL_SOCKET, SO_ERROR,(char*) &optval, &optlen);

switch(optval)

case 0:

//“处于连接状态“

break;

case ECONNREFUSED:

case EHOSTNUMREACH:



4. 项目中使用的情况

// 判断是否连接

int optval, optlen = sizeof(int);

int r = getsockopt(g_sockfd, SOL_SOCKET, SO_ERROR,(char*) &optval, &optlen);

// send HELLO 包

if ((optval == 0) && (r == 0) && (send(g_sockfd,(char*)&g_DAUCommand,sizeof(struct _DAUCommand),0) != SOCKET_ERROR ))



ServiceLog.write_log("[threadOperationWaitTrasferAgain]: try to recv from dau...");

length = recv(g_sockfd,(char *)&command,sizeof(struct _DAUCommand),0);



else



if (connect(g_sockfd,(struct sockaddr*)&g_serv_addr, sizeof(g_serv_addr) ) == 0)



ServiceLog.write_log("[threadOperationWaitTrasferAgain]:connect to DAU success.");

ServiceLog.write_log("[threadOperationWaitTrasferAgain]: try to recv from dau...");

length = recv(g_sockfd,(char *)&command,sizeof(struct _DAUCommand),0);



else



ServiceLog.write_log("[threadOperationWaitTransferAgain]:can't connect to DAU, try again ");

length = 0;

continue;



如何设置 socket.io 来源以限制连接到一个 url

【中文标题】如何设置 socket.io 来源以限制连接到一个 url【英文标题】:how to set socket.io origins to restrict connections to one url 【发布时间】:2013-03-24 04:50:13 【问题描述】:

我们有一个 html 网站和一个为该网站提供服务的 node.js 服务器。 网站和服务器使用 socke.io 交换数据。 我们在文档中发现了这一点:

来源默认为 *:* 允许连接到 Socket.IO 服务器的源。

我们的 html.site 位于 http://questionexample.com/page1 上。 只有这个网站可以连接到我们的服务器。(但每个人都可以连接到那个网站。) 我们如何设置原点?

【问题讨论】:

【参考方案1】:

对于较新版本的 socket.io(直到当前的 4.x.x,您需要将 CORS 来源设置为服务器选项的一部分。

CORS 现在被拆分为自己的模块 - 有关详细信息,请参阅 readme。

默认配置是;


  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204

并限制在一个站点上使用任何子域;

cors: 
        origin: [/\.example\.com$/],
        methods: ["GET", "POST"]
        

这是一个非常简单/基本的配置块,适合那些不使用 express 或除了原始 socket.io 引擎之外的任何东西的人; 编辑:更新了 socket.io 的第 3 版。

// Options for socket.io => 3.0.0
var options = 
        allowUpgrades: true,
        transports: [ 'polling', 'websocket' ],
        pingTimeout: 9000,
        pingInterval: 3000,
        cookie: 'mycookie',
        httpCompression: true,
        cors: '*:*' <---- Allow any origin here [NOTE THE NAME CHANGE]
;

旧版本使用;

// Options for socket.io > 1.0.0
var options = 
        allowUpgrades: true,
        transports: [ 'polling', 'websocket' ],
        pingTimeout: 9000,
        pingInterval: 3000,
        cookie: 'mycookie',
        httpCompression: true,
        origins: '*:*' <---- Allow any origin here
;

io = require('socket.io')(8010, options);

【讨论】:

【参考方案2】:

你可以在服务器端使用你网站的 url 做这样的事情

  if (origin !== 'https://foo.example.com') 
    return callback('origin not allowed', false);
  
  callback(null, true);
);

【讨论】:

【参考方案3】:

如果你深入研究 Socket.io 源代码,你会发现这样几行:

var origin = request.headers.origin || request.headers.referer
  , origins = this.get('origins');

...

var parts = url.parse(origin);
parts.port = parts.port || 80;
var ok =
  ~origins.indexOf(parts.hostname + ':' + parts.port) ||
  ~origins.indexOf(parts.hostname + ':*') ||
  ~origins.indexOf('*:' + parts.port);

如您所见,Socket.io 获取来自客户端的源(或引用者),检索域名和端口, 并与您指定的origins 选项进行比较。

所以有效的origins 值是(* 表示“任何”):

testsite.com:80 http://testsite.com:80 http://*:8080 *:8080 testsite.com:* http://someotherdomain.com:8080 (以空格分隔的多个来源) testsite.com:*/somepath (socket.io 将忽略 /somepath) *:*

而且这些都是无效的(因为没有端口号):

testsite.com http://testsite.com http://testsite.com/somepath

另请注意,如果您将sub.testsite.com 指定为来源值,则testsite.com 将是有效来源。

【讨论】:

【参考方案4】:

我也遇到过类似的问题。 尝试在生产模式下运行节点NODE_ENV=production node app.js。 我有那个代码(as recommended here):

io.configure('production', function()
    console.log("Server in production mode");
    io.enable('browser client minification');  // send minified client
    io.enable('browser client etag'); // apply etag caching logic based on version number
    io.enable('browser client gzip'); // the file
    io.set('log level', 1);           // logging
    io.set('transports', [            // all transports (optional if you want flashsocket)
        'websocket'
        , 'flashsocket'
        , 'htmlfile'
        , 'xhr-polling'
        , 'jsonp-polling'
    ]);
io.set('origins', 'http://questionexample.com/page1:*');
);

并且 Node 在开发模式下运行,所以它根本无法工作。启用生产模式后一切正常。

我知道答案有点晚了,但也许其他人会使用它

【讨论】:

【参考方案5】:

我认为io.set('origins', http://questionexample.com/page1) 应该这样做

【讨论】:

感谢您的回答,但这对我们不起作用。当我们加载网站但无法连接时,我们会收到以下警告:illegal origin 你想接受什么?我认为来源是客户端的IP。为了安全起见,您建议的来源限制也不起作用,因为可以轻松更改网址。您可能想看看客户的Authorisation。 你也需要一个端口号 io.set 在最新版本中不再受支持。 config 在服务器上运行 var socket = require('socket.io')( // options go here ); 更改为 io.origins(['https://foo.example.com:443']);io.origins((origin, callback) =&gt; if (origin !== 'https://foo.example.com') return callback('origin not allowed', false); callback(null, true); ); 请参阅:new-Server-httpServer-options

以上是关于如何判断SOCKET还是连接着的的主要内容,如果未能解决你的问题,请参考以下文章

socket 如何判断远端服务器的连接状态?连接断开,需重连

socket.io的心跳机制是怎么用的

如何判断客户端是不是如何判断是不是与服务器断开了

socket.io 判断用户是在线还是离线

Android 蓝牙开发-打开蓝牙后能不能立即连接固定地址的蓝牙设备??还是需要进行判断啥的?

判断socket断开连接的方法