对于multithreadingTCP客户端执行’close()’时未发送TCP FIN

我在下面写了multithreadingTCP客户端,它基本上产生了一个单独的线程来接收数据但是数据是在主线程中写入的,只是在标准输入上从用户那里获取了输入。

现在,按下了ctrl ^ D然后实现来自循环(围绕getline()调用)并关闭套接字描述符但是在线上没有看到FIN。 但是,用shutdown()替换close()会产生影响。 使用close()没有FIN在线路上发送,但是关闭(fd,SHUT_WR)FIN在线路上发送?

为什么会有这种差异?

#include  #include  #include  #include  #include  #include  #include  void *receiver (void *arg); pthread_t thrid; int sockfd; int reUse = 0; int main (int argc, char *argv[]) { struct sockaddr_in servaddr; struct sockaddr_in clntaddr; char *line; size_t len = 0; size_t read; int bytes; if (argc < 6) { printf ("Usage:%s      [Client IPv4 address] [Client Port]\n", argv[0]); return -1; } /* * AF_INET, AF_INET6, AF_UNIX, AF_NETLINK * SOCK_STREAM (TCP), SOCK_DGRAM (UDP), SOCK_RAW */ if ((sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { printf ("Failed to create socket: %s\n", strerror (errno)); return -1; } /* * set SO_REUSEADDR option for the UDP server socket */ reUse = atoi (argv[3]); if (reUse) { int i = 1; setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &i, sizeof (i)); } bzero (&clntaddr, sizeof (struct sockaddr_in)); if (argc == 8) { printf ("doing bind......\n"); clntaddr.sin_family = AF_INET; clntaddr.sin_port = htons (atoi (argv[7])); inet_aton (argv[6], &clntaddr.sin_addr); if (bind (sockfd, (struct sockaddr *) &clntaddr, sizeof (struct sockaddr_in)) == -1) { perror ("Failed to bind"); close (sockfd); return -1; } } bzero (&servaddr, sizeof (struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons (atoi (argv[2])); inet_aton (argv[1], &servaddr.sin_addr); if (-1 == connect (sockfd, (struct sockaddr *) &servaddr, sizeof (struct sockaddr_in))) { printf ("Failed to connect: %s\n", strerror (errno)); return -1; } if (pthread_create (&thrid, NULL, receiver, NULL) < 0) { printf ("Failed to create thread\n"); } while ((read = getline (&line, &len, stdin)) != -1) { bytes = send (sockfd, line, len, 0); if (bytes < 0) { if (errno == EINTR) continue; else printf ("%Read error %s\n", pthread_self (), strerror (errno)); } } if (0 == atoi (argv[4])) { printf ("doing close()....\n"); close (sockfd); } else if (1 == atoi (argv[4])) { printf ("doing shutdown(..., SHUTRD)....\n"); shutdown (sockfd, SHUT_RD); } else if (2 == atoi (argv[4])) { printf ("doing shutdown(..., SHUTWR)....\n"); shutdown (sockfd, SHUT_WR); } else if (3 == atoi (argv[4])) { printf ("doing shutdown(..., SHUTRDWR)....\n"); shutdown (sockfd, SHUT_RDWR); } if (line) free (line); sleep (atoi (argv[5])); } void * receiver (void *arg) { char buff[512]; int bytes; while (1) { bytes = recv (sockfd, buff, sizeof (buff), 0); if (bytes < 0) { if (errno == EINTR) continue; else printf ("%Read error %s\n", pthread_self (), strerror (errno)); pthread_exit (-1); } else if (bytes == 0) { printf ("connection closed by Peer\n"); close(sockfd); pthread_exit (-1); } else { printf ("Msg Received:%s\n", buff); } } } 

呼叫关闭(WR)将发送FIN,但关闭有一点不同:如果fd引用计数不等于0将不发送FIN。

你可以在关闭之前使用shutdown(socket,SHUT_WR)(套接字)