select多socket写法
linux Select函数用法详解

Socket-SelectSelect在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect、accept、recv或recvfrom 这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。
可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。
下面详细介绍一下。
Select的函数格式:int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set*errorfds,struct timeval *timeout);先说明两个结构体:第一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。
fd_set集合可以通过一些宏由人为来操作,比如清空集合 FD_ZERO(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set *),将一个给定的文件描述符从集合中删除FD_CLR(int ,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。
基于select模型的socket编程

基于select模型的socket编程是指利用select函数来实现多路复用的网络编程方式。
在网络编程中,select模型可以让一个进程监听多个文件描述符(包括socket描述符),并在其中任何一个描述符就绪时立即得到通知,从而可以及时进行处理。
这样就可以很好地解决传统的阻塞I/O模式下只能处理一个连接的问题,提高了网络编程的效率和并发处理能力。
在进行select模型的socket编程时,首先需要创建一个socket,并设置为非阻塞模式。
然后将这个socket加入到select的监听列表中,通过select函数进行监听。
当有连接请求或数据到达时,select函数会返回就绪的文件描述符,再通过判断哪些文件描述符就绪,进行相应的处理。
使用select模型进行socket编程有以下几个优点:1. 提高了网络编程的效率和并发处理能力,可以同时监听多个文件描述符,处理多个连接。
2. 采用非阻塞I/O,避免了频繁的阻塞和唤醒,减少了系统开销。
3. 代码结构相对简单,易于理解和维护。
然而,select模型也存在一些局限性:1. 单个进程能够监视的文件描述符数量存在一定限制,一般不超过1024个。
2. 在文件描述符数量较大时,select的效率会变得很低。
3. select模型在处理大数据量的情况下可能存在效率问题,因为每次调用select函数都需要重新初始化监视列表。
基于select模型的socket编程是一种高效、灵活的网络编程方式,适用于一些对并发性能要求不是特别高的场景。
当然,随着技术的发展和需求的变化,现在有更多更先进的网络编程模型,如epoll和IO多路复用等,可以更好地满足日益增长的网络需求。
通过深入理解并掌握基于select模型的socket编程,我们可以更好地应用于实际项目中,提高网络通讯的效率和并发处理能力,为用户提供更好的使用体验。
同时也能够不断学习和探索更先进的网络编程技术,不断提升自己的技术能力和解决问题的能力。
C#下用select方法实现socket服务端

C#下用select方法实现socket服务端select是一种比较古老但一直被证明性能很好的socket 模式,它可以让你以消息驱动的模式书写socket程序。
网上C++的例子很多,但C#的例子极少。
上代码:[csharp] view plain copynamespace Server { class Program{ // Thread signal. public static ManualResetEvent allDone = newManualResetEvent(false); private static Socket handler = null; private static ArrayList g_CliSocketArr = new ArrayList(); private static Object thisLock = new Object(); public Program() { }public static void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024]; IPAddress ipAddress =IPAddress.Parse("0.0.0.0");//0.0.0.0表示监听本机的所有IP IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = newSocket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp );// Bind the socket to the local endpoint and listen forincoming connections. try{ listener.Bind(localEndPoint);listener.Listen(100); // Start an asynchronous socket to listen for connections.Console.WriteLine("Waiting for a connection...");Thread worker = new Thread(newThreadStart(WorkerThread));//创建一个线程用于处理请求worker.Start(); while (true){ Socket sClient = listener.Accept(); Console.WriteLine("There is a new connection.");g_CliSocketArr.Add(sClient);} } catch (Exception e){ Console.WriteLine(e.ToString());} Console.WriteLine("\nPress ENTER to continue..."); Console.Read(); } public static void WorkerThread(){ Socket socket1 = null;ArrayList readList = new ArrayList(); //readList.Add(socket0); while (true){ lock (thisLock){ readList.Clear();for (int i = 0; i < g_CliSocketArr.Count; i++){ readList.Add(g_CliSocketArr [i]); } }if (readList.Count <= 0){ Thread.Sleep(100);continue; } try{ Socket.Select(readList, null, null, 500); for (int i = 0; i <readList.Count; i++){ socket1 = (Socket)readList[i]; Console.WriteLine("There is a new message from client."); byte[] buffer = new byte[1024];int recLen = socket1.Receive(buffer);if(recLen > 0){ // recLen =socket1.Receive(buffer); } else {//如果返回0,表示客户端已经断开连接,须将此socket关闭然后从连接池中清除Console.WriteLine("Rece 0 length.");for (int ii = 0; ii < g_CliSocketArr.Count; ii++){ Socket s = (Socket)g_CliSocketArr[ii];if (s == socket1)g_CliSocketArr.RemoveAt(ii);}socket1.Shutdown(SocketShutdown.Both);socket1.Close();break; }socket1.Send(buffer,recLen,SocketFlags.None);} } catch (SocketException e){ Console.WriteLine("{0} Error code: {1}.", e.Message, e.ErrorCode);for (int ii = 0; ii < g_CliSocketArr.Count; ii++){ Socket s =(Socket)g_CliSocketArr[ii]; if (s == socket1)g_CliSocketArr.RemoveAt(ii); } socket1.Shutdown(SocketShutdown.Both);socket1.Close(); } }} static voidMain(string[] args){ StartListening(); } }}。
select函数FDISSET函数的作用

select函数FD ISSET 函数的作用select函数FD_ISSET()函数的作用2010-07-27 09:17FD_ZERO(&readfd);FD_SET(sockfd,&readfd);while(1){sin_size=sizeof(struct sockaddr_in);if(select(MAX_CONNECTED_NO,&readfd,NULL,NULL,(structtimeval*)0)0){if(FD_ISSET(sockfd,&readfd)0){if((client_fd=accept(sockfd,(structsockaddr*)&client_sockaddr,&sin_size))==-1){perror("accept");exit(1);}if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1){perror("recv");exit(1);}if(read(client_fd,buf,MAXDATASIZE)0){perror("read");exit(1);}printf("received aconnection:%s",buf);}/*if*/close(client_fd);}/*select*/}/*while*/函数说明select()用来等待文件描述词状态的改变。
参数n代表最大的文件描述词加1,参数readfds、writefds和exceptfds称为描述词组,是用来回传该描述词的读,写或例外的状况。
底下的宏提供了处理这三种描述词组的方式:FD_CLR(inr fd,fd_set*set);用来清除描述词组set中相关fd的位FD_ISSET(int fd,fd_set*set);用来测试描述词组set中相关fd的位是否为真FD_SET(int fd,fd_set*set);用来设置描述词组set中相关fd的位FD_ZERO(fd_set*set);用来清除描述词组set的全部位参数timeout为结构timeval,用来设置select()的等待时间,其结构定义如下struct timeval{time_t tv_sec;time_t tv_usec;};返回值如果参数timeout设为NULL则表示select()没有timeout。
Linux socket select 函数用法详解

linux 的socket函数分为阻塞和非阻塞两种方式,比如accept函数,在阻塞模式下,它会一直等待有客户连接。
而在非阻塞情况下,会立刻返回。
我们一般都希望程序能够运行在非阻塞模式下。
一种方法就是做一个死循环,不断去查询各个socket的状态,但是这样会浪费大量的cpu时间。
解决这个问题的一个方法就是使用select函数。
使用select函数可以以非阻塞的方式和多个socket通信。
当有socket需要处理时,select函数立刻返回,期间并不会占用cpu时间。
例程分析:#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define MYPORT 1234 // 侦听端口#define BACKLOG 5 // 最大可连接客户端数量#define BUF_SIZE 200int fd_A[BACKLOG]; // 连接的FD数组int conn_amount; // 当前连接的数量void showclient(){int i;printf("client amount: %d\n", conn_amount);for (i = 0; i < BACKLOG; i++){printf("[%d]:%d ", i, fd_A[i]);}printf("\n\n");}int main(void){int sock_fd, new_fd; // 侦听sock_fd, 新连接new_fdstruct sockaddr_in server_addr; // server address informationstruct sockaddr_in client_addr; // connector's address informationsocklen_t sin_size;int yes = 1;char buf[BUF_SIZE];int ret;int i;//创建侦听Socketif ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("Create listening socket error!");exit(1);}//配置侦听Socket//SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑。
setsocketoption函数

setsocketoption函数
```c
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
```
- sockfd:表示要设置选项的套接字描述符。
- level:表示选项的协议层。
可以使用SOL_SOCKET来操作通用套接字选项,也可以使用具体协议的常量,如IPPROTO_TCP。
- optname:表示要设置的选项名称。
具体选项可以根据操作系统和协议的不同而有所变化。
常见的选项包括SO_RCVBUF、SO_SNDBUF、
SO_REUSEADDR等。
- optval:表示指向包含要设置的选项值的缓冲区的指针。
- optlen:表示缓冲区的长度。
下面是几个常见的setsockopt函数应用示例:
1.设置套接字接收缓冲区大小
```c
int rcvbuf_size = 1024 * 64; // 设置接收缓冲区为64KB
```
2.设置套接字发送缓冲区大小
```c
int sendbuf_size = 1024 * 64; // 设置发送缓冲区为64KB ```
3.启用套接字地址重用
```c
int reuse = 1; // 启用地址重用
```
4.启用套接字接收超时
```c
```
5. 设置TCP keep-alive选项
```c
int keep_alive = 1; // 启用TCP keep-alive选项
```。
socket通信中select函数的使用和解释
socket通信中select函数的使⽤和解释select函数的作⽤:select()在SOCKET编程中还是⽐较重要的,可是对于初学SOCKET的⼈来说都不太爱⽤select()写程序,他们只是习惯写诸如conncet()、accept()、recv()或recvfrom这样的阻塞程序(所谓阻塞⽅式block,顾名思义,就是进程或是线程执⾏到这些函数时必须等待某个事件发⽣,如果事件没有发⽣,进程或线程就被阻塞,函数不能⽴即返回)。
可是使⽤select()就可以完成⾮阻塞(所谓⾮阻塞⽅式non-block,就是进程或线程执⾏此函数时不必⾮要等待事件的发⽣,⼀旦执⾏肯定返回,以返回值的不同来反映函数的执⾏情况。
如果事件发⽣则与阻塞⽅式相同,若事件没有发⽣则返回⼀个代码来告知事件未发⽣,⽽进程或线程继续执⾏,所以效率⾼)⽅式⼯作的程序,它能够监视我们需要监视的⽂件描述符的变化情况——读写或是异常。
select函数格式:select()函数的格式(所说的是Unix系统下的Berkeley Socket编程,和Windows下的有区别,⼀会⼉说明):Unix系统下解释:int select(int maxfdp, fd_set* readfds, fd_set* writefds, fd_set* errorfds, struct timeval* timeout);先说明两个结构体:第⼀:struct fd_set可以理解为⼀个集合,这个集合中存放的是⽂件描述符(file descriptor),即⽂件句柄,这可以是我们所说的普通意义的⽂件,当然Unix下任何设备、管道、FIFO等都是⽂件形式,全部包括在内,所以,毫⽆疑问,⼀个socket就是⼀个⽂件,socket句柄就是⼀个⽂件描述符。
fd_set集合可以通过⼀些宏由⼈为来操作,⽐如清空集合:FD_ZERO(fd_set*),将⼀个给定的⽂件描述符加⼊集合之中FD_SET(int, fd_set*),将⼀个给定的⽂件描述符从集合中删除FD_CLR(int, fd_set*),检查集合中指定的⽂件描述符是否可以读写FD_ISSET(int, fd_set*)。
python之select与selector
python之select与selectorselect/poll/epoll的区别I/O多路复⽤的本质就是⽤select/poll/epoll,去监听多个socket对象。
参考:select是不断轮询去监听的socket,socket个数有限制,⼀般为1024个(⽂件描述符为1024,该值可以修改);随着⽂件描述符数量增加,轮询⼀回成本增加。
poll采⽤轮询⽅式监听,只不过没有个数限制;epoll不采⽤轮询⽅式去监听,⽽是当socket有变化时通过回调的⽅式主动告知⽤户进程;⽆最⼤链接数的限制。
⽔平触发(Level Triggered),select()和poll()将就绪的⽂件描述符告诉进程后,如果进程没有对其进⾏IO操作,那么下次调⽤select()和poll()的时候将再次报告这些⽂件描述符,所以它们⼀般不会丢失就绪的消息,这种⽅式称为。
边缘触发(Edge Triggered),只告诉进程哪些⽂件描述符刚刚变为就绪状态,它只说⼀遍,如果我们没有采取⾏动,那么它将不会再次告知,这种⽅式称为边缘触发。
selectPython的select()⽅法直接调⽤操作系统的IO接⼝,它监控sockets,open files, and pipes(所有带fileno()⽅法的⽂件句柄)何时变成readable 和writeable, 或者通信错误,select()使得同时监控多个连接变的简单,并且这⽐写⼀个长循环来等待和监控多客户端连接要⾼效,因为select直接通过操作系统提供的C的⽹络接⼝进⾏操作,⽽不是通过Python的解释器。
select使⽤创建两个列表来表⽰输⼊输出信息给select: select()⽅法接收并监控3个通信列表,第⼀个是所有的输⼊的data,就是指外部发过来的数据,第2个是监控和接收所有要发出去的data,第3个监控错误信息;select()返回3个新的list,分别赋值为readable,writable,exceptional。
socket select用法和粘包处理
一、介绍1. 什么是socket select2. 为什么需要使用socket select3. socket select的作用二、socket select的基本用法1. 创建socket2. 使用select函数进行多路复用3. 使用FD_ISSET宏进行套接字状态检测4. 使用FD_SET宏进行套接字状态设置5. 使用FD_CLR宏进行套接字状态清除6. 使用FD_ZERO宏进行套接字集合清空三、socket select的粘包处理1. 什么是粘包2. 如何使用socket select进行粘包处理3. 代码示例四、总结1. socket select的优点2. socket select的局限性3. 对于粘包问题的处理建议---一、介绍1. 什么是socket selectsocket select是一种用于I/O多路复用的机制,它可以同时监视多个socket,当某个或某些socket发生变化时,可以触发相应的操作。
2. 为什么需要使用socket select在网络编程中,往往需要同时处理多个客户端的请求,如果使用传统的阻塞式I/O,需要为每个客户端创建一个线程来处理其请求,这样会导致系统资源的浪费。
而socket select可以通过单线程监听多个socket,极大地提升了服务器的处理效率。
3. socket select的作用socket select主要用于I/O多路复用,它可以监视多个socket的状态,并在其中任何一个socket发生变化时通知用户程序,从而实现高效的并发网络编程。
二、socket select的基本用法1. 创建socket在使用socket select之前,首先需要创建一个socket,并进行绑定、监听等操作,以便服务器可以接受客户端的连接请求。
2. 使用select函数进行多路复用在程序中使用select函数时,需要将所有需要监听的socket添加到一个文件描述符集合中,通过调用select函数来监视这些socket的状态变化。
select套接字的用法
select套接字的用法选择套接字(select socket)是一种用于在多个套接字中选择等待的I/O 操作的机制。
它常用于异步编程和多客户端服务器中,可以同时监听多个套接字事件,以实现高效的并发处理。
在本文中,我们将逐步介绍select 套接字的用法,并提供具体的示例以加深理解。
第一步:导入必要的模块首先,我们需要导入所需的模块来使用select套接字。
在Python中,我们可以使用select模块来实现套接字的select机制。
因此,我们可以通过以下代码导入所需的模块:pythonimport selectimport socketimport sys第二步:创建套接字接下来,我们需要创建一个套接字来进行监听和通信。
我们可以使用socket模块的socket函数来创建一个套接字。
以下是创建TCP套接字的示例代码:python# 创建TCP套接字server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)在此示例中,我们使用的是IPv4地址族(AF_INET)和可靠的、面向连接的传输(SOCK_STREAM)。
第三步:绑定套接字在使用套接字之前,我们需要将其绑定到一个指定的主机和端口号。
我们可以使用套接字的bind方法来完成这一步骤。
python# 绑定套接字server_address = ('localhost', 1234)server_socket.bind(server_address)在此示例中,我们将套接字绑定到本地主机上的1234端口。
第四步:监听连接接下来,我们需要将套接字设置为监听模式,以便能够接受来自客户端的连接请求。
我们可以使用套接字的listen方法来完成这一步骤。
python# 监听连接server_socket.listen(5)在此示例中,我们将套接字设置为最多可以同时处理5个连接请求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
发现网络上较难找多select 多socket的事例。
谢了一个供参考接收端:#include<sys/select.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<unistd.h>#include<pthread.h>#include<stdio.h>#include<string.h>#define MY_MAX(a,b) (a)>(b)?(a):(b)typedef struct{int soc_count;pthread_t tid;fd_set fdset;int exit_flag;int socket_set[32];struct sockaddr_in addr[32];pthread_mutex_t mutex_lock;}UDP_SERVER_CTRL_T;UDP_SERVER_CTRL_T server_ctrl;void * run_thread(void *arg){int i,len;int max_fd = -1;struct sockaddr_in*tmp_sockaddr;struct timeval time_out = {1,0};unsigned char message_buf[1024];int active_socket_count;int addr_len = sizeof(struct sockaddr_in);while(1){FD_ZERO(&server_ctrl.fdset);for (i = 0; i < sizeof(server_ctrl.socket_set)/sizeof(int); i++){max_fd = MY_MAX(server_ctrl.socket_set[i], max_fd);if (server_ctrl.socket_set[i] > 0){FD_SET(server_ctrl.socket_set[i], &server_ctrl.fdset);//printf("check the port socket %d / %d \n",server_ctrl.socket_set[i], ntohs(server_ctrl.addr[i].sin_port));}}time__sec = 10;time__usec = 0;active_socket_count = select(max_fd + 1, &server_ctrl.fdset, NULL,NULL ,&time_out);switch (active_socket_count){case 0:printf("waiting socket time out\n");break;case -1:printf("select error\n");break;default:memset(message_buf, 0 , sizeof(message_buf));for (i = 0; i < sizeof(server_ctrl.socket_set)/sizeof(int); i++) {if (server_ctrl.socket_set[i] < 0){continue;}if( FD_ISSET(server_ctrl.socket_set[i], &server_ctrl.fdset)) {tmp_sockaddr = &server_ctrl.addr[i];len = recvfrom(server_ctrl.socket_set[i],message_buf,sizeof(message_buf), 0, (struct sockaddr *)tmp_sockaddr,&addr_len);message_buf[len] = '\n';printf("recv message: %s \n", message_buf);}}if (i >= sizeof(server_ctrl.socket_set)){printf("fuck error message\n");break;}}if (server_ctrl.exit_flag){printf("run thread exit\n");break;}}return 0;}int create_task(void){int retval = 0;int socket_fd;struct sockaddr_in *sock_addr_p = NULL;int input_port;int port = 0;char c;int i;/*****************************************/int len = 0;unsigned char message_buf[1024];int addr_len = sizeof(struct sockaddr_in);/*****************************************/printf("----------------------------------------------------------\n"); printf("press a create a socket\n");printf("press b del a socket\n");printf("press c exit \n");printf("\n");printf("\n");printf("----------------------------------------------------------\n");c = getchar();input_port = 0;switch(c){case'a':printf("input port\n");scanf("%d", &input_port);for (i = 0; i < sizeof(server_ctrl.socket_set)/sizeof(int); i++){if (server_ctrl.socket_set[i] == -1){sock_addr_p = &server_ctrl.addr[i];break;}}if (i >= sizeof(server_ctrl.socket_set)){printf(" error %d\n",__LINE__);return -1;}bzero(sock_addr_p, sizeof(struct sockaddr_in));sock_addr_p->sin_family = AF_INET;sock_addr_p->sin_addr.s_addr = htonl(INADDR_ANY);sock_addr_p->sin_port = htons(input_port);socket_fd = socket(AF_INET, SOCK_DGRAM, 0);if (socket_fd < 0){printf("create socket fail\n");return -1;}retval = bind(socket_fd, (struct sockaddr *)sock_addr_p,sizeof(struct sockaddr_in));if (retval){printf("bind socket fail\n");close(socket_fd);}if (server_ctrl.socket_set[i] == -1){pthread_mutex_lock(&server_ctrl.mutex_lock);FD_SET(socket_fd, &server_ctrl.fdset);server_ctrl.socket_set[i] = socket_fd;memcpy(&server_ctrl.addr[i], sock_addr_p, sizeof(struct sockaddr_in));pthread_mutex_unlock(&server_ctrl.mutex_lock);}break;case'b':pthread_mutex_lock(&server_ctrl.mutex_lock );for (i = 0; i < sizeof(server_ctrl.socket_set)/sizeof(int); i++) {if (server_ctrl.socket_set[i] > 0){close(server_ctrl.socket_set[i]);FD_CLR(server_ctrl.socket_set[i], &server_ctrl.fdset); server_ctrl.socket_set[i] = -1;break;}}pthread_mutex_unlock(&server_ctrl.mutex_lock );break;case'c':server_ctrl.exit_flag = 1;return 0;}return -1;}int main(int argc, char **argv){int i;int retval = 0;for (i = 0; i < sizeof(server_ctrl.socket_set)/sizeof(int); i++) {server_ctrl.socket_set[i] = -1;}FD_ZERO(&server_ctrl.fdset);pthread_mutex_init(&server_ctrl.mutex_lock ,NULL);pthread_create(&(server_ctrl.tid), NULL, run_thread,NULL);server_ctrl.exit_flag = 0;printf("stupid sizie %d\n", sizeof(server_ctrl.socket_set));while(1){retval = create_task();if (retval == 0){printf("main thread exit\n");break;}}pthread_join(server_ctrl.tid, NULL);pthread_mutex_destroy(&server_ctrl.mutex_lock);return 0;}发送端:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<netdb.h>#define PACKET_COUNT 1000int main(int agrc, char *argv[]){int time_counter = PACKET_COUNT;int socket_fd = -1;char *port_char = argv[1];if (argv[1] == NULL){printf(" input port id\n");return 0;}char meg_buff[512] = {"Hello I am the client"};const int port = atoi(port_char);struct sockaddr_in addr_dst;addr_dst.sin_family = AF_INET;addr_dst.sin_port = htons(port);addr_dst.sin_addr.s_addr = inet_addr("10.2.2.73");socket_fd = socket(AF_INET, SOCK_DGRAM, 0);if (socket_fd < 0){printf("create a socket fail\n");return -1;}while ( 0 < time_counter--){printf("sent %4dth packet port %d\n",PACKET_COUNT - time_counter, port);sprintf(meg_buff,"Hello I am the client %spacket %d\n",argv[1] ,PACKET_COUNT - time_counter);sendto(socket_fd, meg_buff, strlen(meg_buff) + 1,0 , (struct sockaddr*)&(addr_dst), sizeof(addr_dst)); sleep(10);}close(socket_fd);return 0;}代码已经编译通过,压力测试没有问题。