day5 select poll

使用select实现TCP客户端的并发

  1 #include<head.h>
  2 #define SER_PORT  8888             //服务器端口号
  3 #define SER_IP "192.168.122.155"    //服务器ip地址
  4 #define CLI_PORT 6666                //客户端的端口号
  5 #define CLI_IP "192.168.122.155"       //客户端ip地址
  6 int main(int argc, const char *argv[])
  7 {
  8     //1、创建用于通信的套接字文件描述符
  9     int cfd = -1;
 10     cfd = socket(AF_INET, SOCK_STREAM, 0);
 11     if(cfd == -1)
 12     {
 13         perror("socket error");
 14         return -1;
 15     }
 16     printf("cfd = %d\n", cfd);            //3
 17     /*//2、绑定(可选)
 18     //2.1 填充地址信息结构体
 19     struct sockaddr_in cin;
 20     cin.sin_family = AF_INET;
 21     cin.sin_port = htons(CLI_PORT);
 22     cin.sin_addr.s_addr = inet_addr(CLI_IP);
 23     //2.2绑定
 24     if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
 25     {
 26         perror("bind error");
 27         return  -1;
 28     }
 29     printf("bind  success\n");*/
 30     //3、连接服务器
 31     //3.1 填充服务器地址信息结构体
 32     struct sockaddr_in sin;
 33     sin.sin_family =     AF_INET;
 34     sin.sin_port =         htons(SER_PORT);
 35     sin.sin_addr.s_addr = inet_addr(SER_IP);
 36     //3.2 连接
 37     if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
 38     {
 39         perror("connect error");
 40         return -1;
 41     }
 42     printf("connect success\n");
 43     fd_set readfds;
 44     FD_ZERO(&readfds);
 45     FD_SET(0,&readfds);
 46     FD_SET(cfd,&readfds);
 47     //4、收发数据
 48     char buf[128] = "";
 49     while(1)
 50     {
 51         int res=select(cfd+1,&readfds,NULL,NULL,NULL);
 52         if(res==-1)
 53         {
 54             perror("select error");
 55             return -1;
 56         }
 57         else if(res==0)
 58         {
 59             perror("timeout\n");
 60             return -1;
 61         }
 62         if(FD_ISSET(0,&readfds))
 63         {
 64             //清空数组
 65             bzero(buf, sizeof(buf));
 66             printf("请输入>>>");
 67             fgets(buf, sizeof(buf), stdin);   //从终端输入数据
 68             buf[strlen(buf)-1] = 0;          //将换行改为'\0'
 69             //发送给服务器
 70             send(cfd, buf, sizeof(buf), 0);
 71             printf("发送成功\n");
 72             if(strcmp(buf, "quit") == 0)
 73             {
 74                 break;
 75             }
 76         }
 77         if(FD_ISSET(cfd,&readfds))
 78         {
 79             //接收服务器发来的消息
 80             recv(cfd, buf, sizeof(buf), 0);
 81             printf("[%s:%d]:%s\n", SER_IP, SER_PORT, buf);
 82         }
 83     }                                                                                                                                
 84     //5、关闭套接字
 85     close(cfd);
 86     return 0;
 87 }

使用poll实现TCP服务器的并发

  1 #include<head.h>
  2 #define SER_PORT 8888
  3 #define SER_IP "192.168.122.155"
  4 int main(int argc, const char *argv[])
  5 {
  6     //1、创建用于连接的套接字
  7     int sfd = socket(AF_INET, SOCK_STREAM, 0);
  8     //参数1:通信域,表明使用的是ipv4协议
  9     //参数2:通信方式,使用TCP通信
 10     //参数3:0表示之前已经指定协议 IPPROTO_TCP 
 11     if(sfd == -1)
 12     {
 13         perror("socket error");
 14         return -1;
 15     }
 16     printf("sfd = %d\n", sfd);               //3
 17     //将端口号快速重用函数
 18     int reuse = 1;
 19     if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
 20     {
 21         perror("setsockopt error");
 22         return -1;
 23     }
 24     printf("端口号快速重用成功\n");
 25     //2、给当前套接字绑定IP地址和端口号
 26     //2.1填充要绑定的地址信息结构体
 27     struct sockaddr_in sin;
 28     sin.sin_family =     AF_INET;        //通信域
 29     sin.sin_port =         htons(SER_PORT);  //端口号
 30     sin.sin_addr.s_addr =     inet_addr(SER_IP);    //ip地址
 31     //2.2 绑定
 32     if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
 33     {
 34         perror("bind error");
 35         return -1;
 36     }
 37     printf("bind success %s %s %d\n", __FILE__, __func__, __LINE__);
 38     //3、将套接字设置成监听状态
 39     if(listen(sfd, 128) == -1)
 40     {
 41         perror("listen error");
 42         return -1;
 43     }
 44     printf("listen success %s %s %d\n", __FILE__, __func__, __LINE__);
 45     //4、阻塞等待客户端的链接请求
 46     //4.1定义容器接收客户端的地址信息
 47     struct sockaddr_in cin;                  //用于接收地址信息
 48     socklen_t socklen = sizeof(cin);          //用于接收地址信息的大小
 49     int newfd = -1;
 50     struct pollfd pfd[3];
 51     pfd[0].fd=0;
 52     pfd[0].events=POLLIN;
 53     pfd[1].fd=sfd;
 54     pfd[1].events=POLLIN;
 55     while(1)
 56     {
 57         int res = poll(pfd,3,-1);
 58         if(res == -1)
 59         {
 60             perror("poll error");
 61             return -1;
 62         }else if(res == 0)
 63         {
 64             printf("timeout\n");
 65             return -1;
 66         }
 67         if(pfd[1].revents==POLLIN)
 68         {
 69 
 70             //4.2 接收客户端的链接
 71             newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
 72             if(newfd == -1)
 73             {
 74                 perror("accept error");
 75                 return -1;
 76             }
 77             printf("[%s:%d]发来链接请求 %s %s %d\n", \
 78                     inet_ntoa(cin.sin_addr), ntohs(cin.sin_port),__FILE__, __func__, __LINE__);
 79             pfd[2].fd=newfd;
 80             pfd[2].events=POLLIN;
 81         }
 82         //判断0号文件描述符是否在集合中
 83         if(pfd[0].revents==POLLOUT)
 84         {                                                                                                                                                                                                                                                                                                                                                                                                                               
 85             //终端输入
 86             char wbuf[128] = "";
 87             scanf("%s", wbuf);
 88             printf("触发了终端输入事件。。。\n");
 89         }
 90         if(pfd[1].revents==POLLIN||pfd[2].revents==POLLIN)
 91         {
 92             //5、跟客户端进行消息通信
 93             char buf[128] = "";
 94             while(1)
 95             {
 96                 //将数组清空
 97                 bzero(buf, sizeof(buf));
 98                 //读取客户端发来的消息
 99                 //int res = read(newfd, buf, sizeof(buf));
100                 int res = recv(newfd, buf, sizeof(buf), 0);
101                 if(res == 0)
102                 {
103                     printf("客户端已经下线\n");
104                     break;
105                 }
106                 printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
107                 //给客户端发消息
108                 strcat(buf, "*_*");
109                 //write(newfd, buf, sizeof(buf));
110                 send(newfd, buf, sizeof(buf), 0);
111                 printf("发送成功\n");
112             }
113         }
114         //关闭当前通信的套接字
115         close(newfd);
116     }
117     //6、关闭套接字
118     close(sfd);
119     return 0;
120 }

使用poll实现TCP服务器的并发

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值