TCP FIN不能做的多线程TCP客户端“关闭()”发送

编程入门 行业动态 更新时间:2024-10-23 07:16:43
本文介绍了TCP FIN不能做的多线程TCP客户端“关闭()”发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我已经写了下面这基本上生成一个单独的线程接收但是数据被写入在主线程中唯一已采取从标准输入用户输入数据的多线程TCP客户端。

现在,有pressed CTRL ^ D再执行出来的循环(围绕函数getline()调用),并关闭套接字描述符,但没有FIN看到在电线上。但是,更换的close()与shutdown()方法有差别。随着接近()不FIN上线但关机(FD,SHUT_WR)FIN上线送?送

这是为什么不同?

的#include<&stdio.h中GT;#包括LT&;&stdlib.h中GT;#包括LT&;&string.h中GT;#包括LT&; SYS / types.h中>#包括LT&; SYS / socket.h中>#包括LT&; netinet / in.h中>#包括LT&;&errno.h中GT;void *的接收器(无效* ARG);的pthread_t THRID;INT的sockfd;INT REUSE = 0;INT主(INT ARGC,CHAR *的argv []){    结构SOCKADDR_IN servaddr;    结构SOCKADDR_IN clntaddr;    字符*线;    为size_t LEN = 0;    SIZE_T阅读;    诠释字节;    如果(argc个6;)    {        的printf            (用法:%S<服务器IPv4地址><服务器端口>< SO_REUSEADDR是(1)/否(0))><关闭(0)/ SHUT_RD(1)/ SHUT_WR(2)/ SHUT_RDWR (3)><睡眠(以秒为单位)GT;客户端的IPv4地址] [客户端端口] \\ n             的argv [0]);        返回-1;    }    / *     * AF_INET,AF_INET6,AF_UNIX,AF_NETLINK     * SOCK_STREAM(TCP),SOCK_DGRAM(UDP),SOCK_RAW     * /    如果((的sockfd =插座(AF_INET,SOCK_STREAM,IPPROTO_TCP))== -1)    {        的printf(无法创建套接字:%S \\ n字符串错误(错误));        返回-1;    }    / *     *对于UDP服务器套接字设置SO_REUSEADDR选项     * /    重用=的atoi(argv的[3]);    如果(再利用)    {        INT I = 1;        setsockopt的(的sockfd,SOL_SOCKET,SO_REUSEADDR,(无效*)及我,                    的sizeof(I));    }    bzero(安培; clntaddr,的sizeof(结构SOCKADDR_IN));    如果(ARGC == 8)    {        的printf(做绑定...... \\ n);        clntaddr.sin_family = AF_INET;        clntaddr.sin_port = htons(与atoi(argv的[7]));        INET_ATON(argv的[6],&放大器; clntaddr.sin_addr);        如果(绑定            (的sockfd,(结构sockaddr *)及clntaddr,             的sizeof(结构SOCKADDR_IN))== -1)        {            PERROR(无法绑定);            接近(的sockfd);            返回-1;        }    }    bzero(安培; servaddr,的sizeof(结构SOCKADDR_IN));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(与atoi(argv的[2]));    INET_ATON(的argv [1],&放大器; servaddr.sin_addr);    如果(-1 ==        连接(的sockfd,(结构sockaddr *)及servaddr,                 的sizeof(结构SOCKADDR_IN)))    {        的printf(无法连接:%S \\ n字符串错误(错误));        返回-1;    }    如果(在pthread_create(安培; THRID,NULL,接收机,NULL)℃的)    {        的printf(无法创建线程\\ n);    }    而((读=函数getline(安培;线,&安培;!LEN,标准输入))= - 1)    {        字节=送(的sockfd,线,LEN,0);        如果(字节℃,)        {            如果(错误== EINTR)                继续;            其他                的printf(%读取错误%S \\ n,pthread_self()                        字符串错误(错误));        }    }    如果(0 ==与atoi(argv的[4]))    {        的printf(做的close()... \\ n);        接近(的sockfd);    }    否则如果(1 ==与atoi(argv的[4]))    {        的printf(做关机(...,SHUTRD).... \\ n);        关机(的sockfd,SHUT_RD);    }    否则如果(2 ==与atoi(argv的[4]))    {        的printf(做关机(...,SHUTWR).... \\ n);        关机(的sockfd,SHUT_WR);    }    否则如果(3 ==与atoi(argv的[4]))    {        的printf(做关机(...,SHUTRDWR).... \\ n);        关机(的sockfd,SHUT_RDWR);    }    如果(线)        免费(线);    睡眠(与atoi(argv的[5]));}无效*接收器(无效* ARG){    字符的buff [512];    诠释字节;    而(1)    {        字节=的recv(的sockfd,浅黄色,sizeof的(BUFF),0);        如果(字节℃,)        {            如果(错误== EINTR)                继续;            其他                的printf(%读取错误%S \\ n,pthread_self()                        字符串错误(错误));            了pthread_exit(-1);        }        否则,如果(字节== 0)        {            的printf(由同侪\\ n连接关闭);            接近(的sockfd);            了pthread_exit(-1);        }        其他        {            的printf(消息收稿日期:%S \\ n,浅黄色);        }    }}

解决方案

您可以关闭之前关闭使用(插座,SHUT_WR)(插座)

I have written below multi-threaded TCP client which basically spawns a separate thread for receiving the data however the data is being written in the main thread only having taken input from the user on standard input.

Now, having pressed ctrl^D then implementation comes out of the loop (around the getline () call) and closes the socket descriptor but no FIN is seen on the wire. However, replacing close() with shutdown () makes a difference. With close() no FIN is sent on the wire but with shutdown(fd, SHUT_WR) FIN is sent on the wire?

Why is this difference?

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <errno.h> 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 <Server Ipv4 address> <Server Port> <SO_REUSEADDR Yes(1)/No(0))> <Close(0)/SHUT_RD(1)/SHUT_WR(2)/SHUT_RDWR(3)> <sleep (in sec)> [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); } } }

解决方案

you can use shutdown( socket, SHUT_WR) before close(socket)

更多推荐

TCP FIN不能做的多线程TCP客户端“关闭()”发送

本文发布于:2023-11-25 09:06:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1629157.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:能做   多线程   客户端   TCP   FIN

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!