C TCP无法检测到断开的连接

时间:2018-09-06 10:55:55

标签: c sockets tcp ip tcp-ip

我有用C编写的基本tcp应用程序。它基本上将数据发送到tcp服务器。我已经用交叉电缆连接了两台PC。我从一个发送数据,并从另一个成功获取数据。我已经建立了这种机制来测试是否由于不正常的方式(电缆等断裂)而导致连接断开,我希望作为客户端得到通知。但是事情并没有如我所愿。如果我手动停止tcpserver,客户端会收到通知,但是当我启动程序时,连接建立,数据开始流动,然后拔下电缆,双方的行为就好像什么都没有发生。客户端仍然可以正确发送数据,服务器仍然显示客户端已连接,但是数据流停止了。几分钟后,我再次插入电缆,被视为已发送但未发送的数据突然刷新,然后程序继续正常运行。我怎样才能检测到这种断开的连接?任何帮助,将不胜感激。这是代码;

#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

int main() {
const char* server_name = "192.168.5.2";
const int server_port = 30152;

struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;

// creates binary representation of server name
// and stores it as sin_addr
// http://beej.us/guide/bgnet/output/html/multipage/inet_ntopman.html
inet_pton(AF_INET, server_name, &server_address.sin_addr);

// htons: port in network order format
server_address.sin_port = htons(server_port);

// open a stream socket
int sock;
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
    printf("could not create socket\n");
    return 1;
}

// TCP is connection oriented, a reliable connection
// **must** be established before any data is exchanged
if (connect(sock, (struct sockaddr*)&server_address,
            sizeof(server_address)) < 0) {
    printf("could not connect to server\n");
    return 1;
}

// send

// data that will be sent to the server
const char* data_to_send = "HELLO THIS IS DATA!";
while(1)
{
    int err = send(sock, data_to_send, strlen(data_to_send), 0);

    if(err==-1)
    {
        printf("ERROR \n");
        break;
    }
    else
    {
        printf("sent  \n");
        sleep(1);
    }

}
printf("EOP\n");

// close the socket
close(sock);
return 0;
}

1 个答案:

答案 0 :(得分:4)

如果TCP连接的对等方关闭该连接,它将导致您端的recv调用返回0。这就是检测关闭(但不断开)连接的方法。

如果当前当前没有从对等方接收任何信息,则需要在TCP之上建立一个协议,其中包括接收数据。

此外,由于存在大量的重传和超时,发送可能无法直接检测到断开的连接(例如电缆丢失等)。最好的方法还是再次实现某种覆盖TCP的协议,例如,其中包含一种希望您答复的“您在那里”消息。如果在特定的超时时间内未收到对“您在那里”消息的答复,请考虑连接断开并断开连接。