#include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 #include<sys/types.h>
5 #include<sys/stat.h>
6 #include<string.h>
7 #include<arpa/inet.h>
8 #include<ctype.h>
9 int main(int argc,const char * argv[])
10 {
11 if(argc<2)
12 {
13 printf("eg: ./a.out port\n");
14 exit(1);
15 }
16 struct sockaddr_in serv_addr;
17 socklen_t serv_len=sizeof(serv_addr);
18 int port =atoi(argv[1]);
19 //创建套接字
20 int lfd=socket(AF_INET,SOCK_STREAM,0);
21 if(lfd==-1)
22 {
23 perror("socket error");
24 exit(-1);
25 }
26 //lfd绑定IP和端口
27 memset(&serv_addr,0,sizeof(serv_addr));
28 serv_addr.sin_family=AF_INET;//地址族
29 serv_addr.sin_port=htons(INADDR_ANY);//监听本机所有IP
30 serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);//设置端口
31 //绑定IP和端口
32 int ret=bind(lfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
33 if(ret==-1)
34 {
35 perror("bind error");
36 exit(1);
37 }
38 //设置最大监听个数
39 listen(lfd,36);
40 struct sockaddr_in client_addr;
socklen_t cli_len=sizeof(client_addr);
42 //要检测的文件描述符最大值
43 int maxfd=lfd;
44 //创建集合
45 fd_set reads,temp;
46 //初始化集合
47 FD_ZERO(&reads);
48 FD_SET(lfd,&reads);
49 while(1)
50 {
51 //委托内核做IO检测
52 temp=reads;
53 ret=select(maxfd+1,&temp,NULL,NULL,NULL);
54 if(ret==-1)
55 {
56 perror("select error");
57 exit(1);
58 }
59 //客户端发起了新连接
60 if(FD_ISSET(lfd,&temp))
61 {
62 //接受连接请求-accept不阻塞
63 int cfd=accept(lfd,(struct sockaddr*)&client_addr,&cli_len);
64 if(cfd==-1)
65 {
66 perror("accept error\n");
67 exit(1);
68 }
69 char ip[64];
printf("new client IP:%s,port:%d\n",inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ip,sizeof(ip)),ntoh s(client_addr.sin_port));
71 //将cfd加入到待检测的集合中,下一次就可以进行检测
72 FD_SET(cfd,&reads);
73 //更新最大文件描述符
74 maxfd=cfd<maxfd?maxfd:cfd;
75 }
76 //已经连接的客户端有数据到达
77 int i;
78 for(i=lfd+1;i<maxfd;i++)
79 {
80 if(FD_ISSET(i,&temp))
81 {
82 char buf[1024]={0};
83 int len =recv(i,buf,sizeof(buf),0);
84 if(len==-1)
85 {
86 perror("recv error\n");
87 exit(1);
88 }
89 if(len==0)
90 {
91 printf("客户端断开连接\n");
92 close(i);
93 //从集合里删除以关闭的客户端
94 FD_CLR(i,&reads);
95 }
96 else
97 {
98 printf("recv buf :%s\n",buf);
99 send(i,buf,strlen(buf)+1,0);
100 }
101 }
102 }
103 }
104
105 close(lfd);
106 return 0;
107 }
多路I/O转接服务器
最新推荐文章于 2025-07-02 22:16:08 发布