Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TCP套接字recv,指示“;“意外”;成功发送后断开连接_C_Sockets_Tcp - Fatal编程技术网

TCP套接字recv,指示“;“意外”;成功发送后断开连接

TCP套接字recv,指示“;“意外”;成功发送后断开连接,c,sockets,tcp,C,Sockets,Tcp,我有一个处于阻塞模式的TCP套接字,用于请求/响应协议的客户端。有时我发现,如果某个套接字未使用一两分钟,则send调用将成功并指示已发送的所有字节,但下面的recv返回零,表示已关闭。我在Windows和Linux客户机上都看到了这一点 服务器人员告诉我,如果他们已经收到数据,他们总是在关机前发送一些响应,但是如果服务器资源不足,他们可能会关闭一个尚未收到任何数据的套接字 我看到的情况是否表明服务器在我不使用连接时关闭了连接,那么为什么发送然后成功 在这种情况下,自动检测请求的正确方法是什么,

我有一个处于阻塞模式的TCP套接字,用于请求/响应协议的客户端。有时我发现,如果某个套接字未使用一两分钟,则
send
调用将成功并指示已发送的所有字节,但下面的
recv
返回零,表示已关闭。我在Windows和Linux客户机上都看到了这一点

服务器人员告诉我,如果他们已经收到数据,他们总是在关机前发送一些响应,但是如果服务器资源不足,他们可能会关闭一个尚未收到任何数据的套接字

我看到的情况是否表明服务器在我不使用连接时关闭了连接,那么为什么
发送
然后成功

在这种情况下,自动检测请求的正确方法是什么,以便在新连接上重新发送请求,但请记住,如果服务器实际收到某些请求两次,可能会产生意外影响

//not full code (buffer management, wrapper functions, etc...)
//no special flags/options are being set, just socket then connect
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, addr, addrlen);
//some time later after many requests/responses, normally if was inactive for a minute
//sending about 50 bytes for requests, never actually seen it loop, or return 0
while (more_to_send) check(send(sock, buffer, len, 0));
//the very first recv returns 0, never seen it happen part way through a response (few KB to a couple of MB)
while (response_not_complete) check(recv(sock, buffer, 4096, 0));
  • 如果您没有从服务器获得请求的应用程序确认,请重新发送它
  • 将您的事务设计为这样,以便重新发送它们不会造成不良影响
      • 如果您没有从服务器获得请求的应用程序确认,请重新发送它
      • 将您的事务设计为这样,以便重新发送它们不会造成不良影响
      我看到的情况是否表明服务器已关闭 连接,而我不使用它

      ,那么为什么send会成功呢

      send()的成功告诉您,传入send()的部分(或全部)数据已成功复制到内核内缓冲区,并且从现在起,操作系统负责尝试将这些字节传递给远程对等方

      特别是,它并不表示这些字节实际上已经通过网络(尚未)或已被服务器成功接收

      自动检测此情况的正确方法是什么 在本例中,请求在新连接上重新发送,但与 请注意,如果服务器实际收到一些请求两次,则 会产生意想不到的影响吗

      //not full code (buffer management, wrapper functions, etc...)
      //no special flags/options are being set, just socket then connect
      sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      connect(sock, addr, addrlen);
      //some time later after many requests/responses, normally if was inactive for a minute
      //sending about 50 bytes for requests, never actually seen it loop, or return 0
      while (more_to_send) check(send(sock, buffer, len, 0));
      //the very first recv returns 0, never seen it happen part way through a response (few KB to a couple of MB)
      while (response_not_complete) check(recv(sock, buffer, 4096, 0));
      
      正如EJP所建议的,最好的方法是设计通信协议,使发送同一请求两次与发送一次没有不同的效果。一种方法是为您发送的每条消息添加一个唯一的ID,并向服务器添加一些逻辑,这样,如果服务器接收到一条ID与它已经处理的ID相同的消息,它会将该消息作为副本丢弃

      让服务器向每条消息发回一个明确的响应(这样您就可以确定您的消息是否已通过并已被处理)可能会有所帮助,但当然,您必须开始担心这样的情况:您的消息已被接收和处理,但TCP连接在响应返回给您之前中断,等等

      您可以做的另一件事(如果您还没有这样做)是监视TCP套接字的状态(通过select()、poll()或类似方式),以便在远程对等方关闭其套接字末端时立即通知您的程序(通过套接字select()-ing将其设置为ready for read)。这样,您就可以在尝试发送()命令之前很好地处理关闭的TCP连接,而不仅仅是在之后才了解它,而且这应该是一个不太难处理的情况,因为在这种情况下,不存在命令是否“通过”的问题

      我看到的情况是否表明服务器已关闭 连接,而我不使用它

      ,那么为什么send会成功呢

      send()的成功告诉您,传入send()的部分(或全部)数据已成功复制到内核内缓冲区,并且从现在起,操作系统负责尝试将这些字节传递给远程对等方

      特别是,它并不表示这些字节实际上已经通过网络(尚未)或已被服务器成功接收

      自动检测此情况的正确方法是什么 在本例中,请求在新连接上重新发送,但与 请注意,如果服务器实际收到一些请求两次,则 会产生意想不到的影响吗

      //not full code (buffer management, wrapper functions, etc...)
      //no special flags/options are being set, just socket then connect
      sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      connect(sock, addr, addrlen);
      //some time later after many requests/responses, normally if was inactive for a minute
      //sending about 50 bytes for requests, never actually seen it loop, or return 0
      while (more_to_send) check(send(sock, buffer, len, 0));
      //the very first recv returns 0, never seen it happen part way through a response (few KB to a couple of MB)
      while (response_not_complete) check(recv(sock, buffer, 4096, 0));
      
      正如EJP所建议的,最好的方法是设计通信协议,使发送同一请求两次与发送一次没有不同的效果。一种方法是为您发送的每条消息添加一个唯一的ID,并向服务器添加一些逻辑,这样,如果服务器接收到一条ID与它已经处理的ID相同的消息,它会将该消息作为副本丢弃

      让服务器向每条消息发回一个明确的响应(这样您就可以确定您的消息是否已通过并已被处理)可能会有所帮助,但当然,您必须开始担心这样的情况:您的消息已被接收和处理,但TCP连接在响应返回给您之前中断,等等


      您可以做的另一件事(如果您还没有这样做)是监视TCP套接字的状态(通过select()、poll()或类似方式),以便在远程对等方关闭其套接字末端时立即通知您的程序(通过套接字select()-ing将其设置为ready for read)。这样,您就可以在尝试发送()命令之前很好地处理关闭的TCP连接,而不仅仅是在之后才了解它,而且这应该是一个不太难处理的情况,因为在这种情况下,不存在命令是否“通过”的问题。

      send
      使用第四个参数,
      flags
      ,您没有指定的。如果是这样,标志将是随机的,它们可能会影响传输。同样,对于
      recv
      My bad it