当前位置: 首页 > 面试题库 >

Linux套接字:如何在客户端程序中检测断开的网络?

任昊阳
2023-03-14
问题内容

我正在调试基于ac的linux socket程序。作为网站上所有可用的示例,我应用了以下结构:

sockfd= socket(AF_INET, SOCK_STREAM, 0);

connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

send_bytes = send(sockfd, sock_buff, (size_t)buff_bytes, MSG_DONTWAIT);

当删除服务器关闭其服务器程序时,我可以检测到断开连接。但是,如果拔下以太网电缆,则send函数仍然返回正值,而不是-1。

假设无法更改服务器端,如何在客户端程序中检查网络连接?


问题答案:

但是,如果拔下以太网电缆,则send函数仍然返回正值,而不是-1。

首先,您应该知道send实际上并没有发送任何内容,它只是一个内存复制功能/系统调用。它将数据从您的进程复制到内核-
有时,内核将获取数据并将其打包在段和数据包中之后发送到另一端。因此send,只能在以下情况下返回错误:

  • 套接字无效(例如伪造的文件描述符)
  • 连接显然无效,例如,它尚未建立或已经以某种方式终止(FIN,RST,超时-见下文)
  • 没有更多空间可以复制数据

最主要的一点是,send它不会发送任何内容,因此 其返回代码不会告诉您有关数据实际到达另一端的任何信息

回到您的问题,当TCP发送数据时,它期望在合理的时间内得到有效的确认。如果没有得到,它将重新发送。它多久发送一次?每个TCP堆栈的处理方式都不同,但是规范是使用指数补偿。也就是说,首先等待1秒,然后等待2,再等待4,依此类推。在某些堆栈上,此过程可能需要几分钟。

最主要的一点是,在中断的情况下,TCP 只会在经过相当长时间的静默后才 声明连接死亡(在Linux上,它会执行15次重试-超过5分钟)。

解决此问题的一种方法是在您的应用程序中实现某种确认机制。例如,您可以向服务器发送请求,“ 在5秒钟内回复,否则我将宣布此连接已死
”,然后recv超时。



 类似资料:
  • 我正在编写一个使用tcp套接字的服务器/客户端应用程序,我的问题是如何检测半开放连接,我计划使用keep-alive但有些人建议我做我自己的协议,所以我现在的计划是: 在服务器端: 服务器会等待10秒等待客户端发送数据,如果在给定的时间内服务器没有收到客户端的消息,服务器会将客户端标记为断开连接,否则,如果服务器收到客户端的消息,则会重新设置计时器。 我现在的问题是,这样行吗?还是我做错了?还是一

  • 我已经编写了java客户端服务器套接字连接代码。因为服务器接受客户机连接,然后服务器使用PrintStream发送数据,客户机在readline()中读取数据。在此之后,客户端将在readline中等待服务器。如果存在网络断开,客户端将在readline中保持等待,并且从不从readline退出。是否有一种方法从客户端本身检测断开?或者我是否必须编写新的心跳线程来检查网络断开?

  • 我想检查一下我的客户是否断开了连接。根据我的研究,一种可能的方式是我可以继续给客户写信。如果客户端未能接收到消息,则表示已断开连接。我向相应的客户端发送消息“Checking Connection:Client”clientNo。 我将clientNo 1连接到服务器,它接收 客户1 但是当我将另一个客户端连接到服务器时,我的clientNo1停止接收来自服务器的消息,我的clientNo2现在将

  • 当我再次调用时,第二次调用将按预期返回。但我想明白,为什么第一次打电话成功了?我是否遗漏了某些特定于TCP的细节?这种奇怪的(对我来说)行为只针对{活动,错误}连接。

  • 我正在使用C#window应用程序表单对TCP多线程服务器进行工作,我正在尝试检测客户端的机器是否关闭并断开与服务器的连接。看了一些帖子,有了一些想法: 如何确定tcp是否连接? 我的代码如下: 多谢帮忙。

  • 我正在开发一个与许多客户端连接的服务器。我需要知道客户端何时与服务器断开连接。因此,每个客户端都向服务器发送一个特定的字符。如果两秒钟后没有收到字符,那么我应该断开服务器与客户端的连接(释放为此客户端分配的资源)。 这是我的服务器的主要代码: 第一个问题是,我用来识别在线客户端的方式(每秒发送特定消息)是否是一种好方法? 如果它是好的,我如何使用检测与女巫客户端相关,然后如何断开密钥与服务器的连接