本文共 2115 字,大约阅读时间需要 7 分钟。
A, B两端tcp建立连接后, 如果中间的交换机断网、断电, 或者B端突然断电, 那么A是无感知的(不考虑心跳机制)。 有些书上喜欢把这种连接叫半开连接, 其实我更愿意叫它为死连接。
此时, 如果A端send一些数据, 会怎样呢? 只要A端的发送内核缓冲区没有满(一般都没满), 那么send函数就是成功返回得, 很显然, 在B端是接收不到数据的。 这再次说明了, send函数和实际发送数没有半毛钱的关系, 这一点, 我们在之前的博文中多次说过。
A发送数据后, 期望收到B的ACK包, 但显然收不到, 于是, A端的协议栈会自动进行重传, 这是tcp最基本的机制之一。 当重传次数达到一定上线后, 就会发RST包, 重置连接, 死连接就彻底死了。
我现在暂时无法构造出上述断网的场景, 有兴趣的可以可以帮试试, 代码如下:
服务端:
#include客户端:#include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(){ int sockSrv = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.s_addr = INADDR_ANY; addrSrv.sin_port = htons(8765); bind(sockSrv, (const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); listen(sockSrv, 5); struct sockaddr_in addrClient; int len = sizeof(struct sockaddr_in); int sockConn = accept(sockSrv, (struct sockaddr *)&addrClient, (socklen_t*)&len); while(1) { getchar(); char szRecvBuf[1001] = {0}; int iRet = recv(sockConn, szRecvBuf, sizeof(szRecvBuf) - 1, 0); printf("iRet is %d\n", iRet); } getchar(); close(sockConn); close(sockSrv); return 0;}
#include一起来试试吧。 有疑问请反馈。#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(){ int sockClient = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr("10.100.70.140"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8765); connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); #define N 2000 char szSendBuf[N] = {0}; for(unsigned int i = 0; i < N; i++) //×Ö·ûÊý×é×îºóÒ»¸ö×Ö·û²»ÒªÇóÊÇ¡®\0¡¯ { szSendBuf[i] = 'a'; } int total = 0; while(1) { int iRet = send(sockClient, szSendBuf, sizeof(szSendBuf) , 0); total += iRet; printf("iRet is %d, total send is %d\n", iRet, total); getchar(); } close(sockClient); return 0;}
睡觉。
转载地址:http://nnwti.baihongyu.com/