日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux网络编程——tcp并发服务器(poll实现)

發(fā)布時間:2023/11/30 linux 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux网络编程——tcp并发服务器(poll实现) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

https://blog.csdn.net/lianghe_work/article/details/46535859

想詳細徹底地了解poll或看懂下面的代碼請參考《Linux網(wǎng)絡(luò)編程——I/O復(fù)用之poll函數(shù)》

代碼:

  • #include <string.h>
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <unistd.h>
  • #include <sys/select.h>
  • #include <sys/time.h>
  • #include <sys/socket.h>
  • #include <netinet/in.h>
  • #include <arpa/inet.h>
  • #include <poll.h>
  • #include <errno.h>
  • #define OPEN_MAX 100
  • int main(int argc, char *argv[])
  • {
  • //1.創(chuàng)建tcp監(jiān)聽套接字
  • int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  • //2.綁定sockfd
  • struct sockaddr_in my_addr;
  • bzero(&my_addr, sizeof(my_addr));
  • my_addr.sin_family = AF_INET;
  • my_addr.sin_port = htons(8000);
  • my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  • bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
  • //3.監(jiān)聽listen
  • listen(sockfd, 10);
  • //4.poll相應(yīng)參數(shù)準備
  • struct pollfd client[OPEN_MAX];
  • int i = 0, maxi = 0;
  • for(;i<OPEN_MAX; i++)
  • client[i].fd = -1;//初始化poll結(jié)構(gòu)中的文件描述符fd
  • client[0].fd = sockfd;//需要監(jiān)測的描述符
  • client[0].events = POLLIN;//普通或優(yōu)先級帶數(shù)據(jù)可讀
  • //5.對已連接的客戶端的數(shù)據(jù)處理
  • while(1)
  • {
  • int ret = poll(client, maxi+1, -1);//對加入poll結(jié)構(gòu)體數(shù)組所有元素進行監(jiān)測
  • //5.1監(jiān)測sockfd(監(jiān)聽套接字)是否存在連接
  • if((client[0].revents & POLLIN) == POLLIN )
  • {
  • struct sockaddr_in cli_addr;
  • int clilen = sizeof(cli_addr);
  • int connfd = 0;
  • //5.1.1 從tcp完成連接中提取客戶端
  • connfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
  • //5.1.2 將提取到的connfd放入poll結(jié)構(gòu)體數(shù)組中,以便于poll函數(shù)監(jiān)測
  • for(i=1; i<OPEN_MAX; i++)
  • {
  • if(client[i].fd < 0)
  • {
  • client[i].fd = connfd;
  • client[i].events = POLLIN;
  • break;
  • }
  • }
  • //5.1.3 maxi更新
  • if(i > maxi)
  • maxi = i;
  • //5.1.4 如果沒有就緒的描述符,就繼續(xù)poll監(jiān)測,否則繼續(xù)向下看
  • if(--ret <= 0)
  • continue;
  • }
  • //5.2繼續(xù)響應(yīng)就緒的描述符
  • for(i=1; i<=maxi; i++)
  • {
  • if(client[i].fd < 0)
  • continue;
  • if(client[i].revents & (POLLIN | POLLERR))
  • {
  • int len = 0;
  • char buf[128] = "";
  • //5.2.1接受客戶端數(shù)據(jù)
  • if((len = recv(client[i].fd, buf, sizeof(buf), 0)) < 0)
  • {
  • if(errno == ECONNRESET)//tcp連接超時、RST
  • {
  • close(client[i].fd);
  • client[i].fd = -1;
  • }
  • else
  • perror("read error:");
  • }
  • else if(len == 0)//客戶端關(guān)閉連接
  • {
  • close(client[i].fd);
  • client[i].fd = -1;
  • }
  • else//正常接收到服務(wù)器的數(shù)據(jù)
  • send(client[i].fd, buf, len, 0);
  • //5.2.2所有的就緒描述符處理完了,就退出當前的for循環(huán),繼續(xù)poll監(jiān)測
  • if(--ret <= 0)
  • break;
  • }
  • }
  • }
  • return 0;
  • }

  • 運行結(jié)果:

    總結(jié)

    以上是生活随笔為你收集整理的Linux网络编程——tcp并发服务器(poll实现)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。