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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

I/O多路转接之poll——基于TCP协议

發布時間:2023/12/4 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 I/O多路转接之poll——基于TCP协议 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 函數


a. 參數:

(1)fds:是一個struct pollfd結構類型的指針,指向用于存放需要檢測狀態的Socket描述符;

每當調用這個函數之后,系統不會清空這個數組,操作起來比較方便;特別是對于socket連接比較多的情況下,在一定程度上可以提高處理的效率;這一點與select()函數不同,調用select()函數之后,select()函數會清空它所檢測的socket描述符集合,導致每次調用select()之前都必須把socket描述符重新加入到待檢測的集合中;因此,select()函數適合于只檢測一個socket描述符的情況,而poll()函數適合于大量socket描述符的情況;

  • fd:表示所要關心的文件描述符;

  • events:表示該文件描述符所關心的事件,這是一個輸入型參數,要告訴操作系統這個文件描述符對應的事件所關心的操作事件是什么,比如讀或寫;

  • revents:表示當poll返回時告訴用戶什么操作事件是就緒的,比如如果POLLIN是就緒的,那么返回時revent的值就是POLLIN,告訴用戶fd事件的POLLIN是就緒的;是一個輸出型參數。


  • (2)nfds:標記指針fds所指向的結構體元素的總數量;


    (3)timeout:poll函數調用阻塞的時間,單位:毫秒。(和select的一樣)

    如果參數timeout設為:

  • INFTIM:select將一直被阻塞,直到某個文件描述符上發生了事件。

  • 0:select將以非阻塞方式等,即檢測描述符集的狀態后立即返回,并不等待外部事件的發生。

  • 大于0的值:poll()函數會阻塞timeout所指定的毫秒時間長度之后返回,如果在指定的時間段里沒有事件發生,select將超時返回0。


  • c. 返回值
    (1)成功:則返回fds指針所指向的內容中準備好的讀、寫或出錯狀態的那些socket描述符的總數量(返回值>0);
    (2)poll函數調用失敗:返回-1,同時會自動設置全局變量errno;;
    (3)超過timeout時間,返回0。(沒有任何socket描述符準備好讀、寫,或出錯)


    2. poll和select對比

    (1)不同:

  • select使用三個位圖來表示三個fdset的方式,poll使用一個 pollfd的指針實現。

  • pollfd結構包含了要監視的event和發生的event,不再使用select“參數-值”傳遞的方式。

  • pollfd并沒有最大數量限制(但是數量過大后性能也是會下降)。?

  • (2)相同:

  • 和select函數一樣,poll返回后,需要輪詢pollfd來獲取就緒的描述符。

  • 從上面看,select和poll都需要在返回后,通過遍歷文件描述符來獲取已經就緒的socket。事實上,同時連接的大量客戶端在一時刻可能只有很少的處于就緒狀態,因此隨著監視的描述符數量的增長,其效率也會線性下降。


  • 3.代碼實現

    //poll_server.c1?#include<stdio.h>2?#include<stdlib.h>3?#include<assert.h>4?#include<poll.h>5?#include<unistd.h>6?#include<sys/socket.h>7?#include<sys/types.h>8?#include<arpa/inet.h>9?#include<netinet/in.h>10?11?#define?_BACKLOG_?512?#define?_NUM_?1013?14?static?void?usage(const?char*?proc)15?{16?????printf("usage:%s?[ip]??[port]\n",proc);17?}18?static?int?startup(char*?ip,int?port)19?{20?????assert(ip);21?????//22?????int?sock=socket(AF_INET,SOCK_STREAM,0);23?????if(sock<0)24?????{25?????????perror("socket");26?????????exit(1);27?????}28?????//29?????struct?sockaddr_in?local;30?????local.sin_family=AF_INET;31?????local.sin_port=htons(port);32?????local.sin_addr.s_addr=inet_addr(ip);33?????//34?????if(bind(sock,(struct?sockaddr*)&local,sizeof(local))<0)35?????{36?????????perror("bind");37?????????exit(2);38?????}39?????if(listen(sock,_BACKLOG_)<0)40?????{41?????????perror("listen");42?????????exit(3);43?????}44?????return?sock;45?}46?int?main(int?argc,char*?argv[])47?{48?????if(argc!=3)49?????{50?????????usage(argv[0]);51?????????exit(1);52?????}53?????char*?ip=argv[1];54?????int?port=atoi(argv[2]);55?56?????int?listen_sock=startup(ip,port);57?58?????struct?sockaddr_in?client;59?????socklen_t?len=sizeof(client);60?61?????struct?pollfd?fds[_NUM_];62?????int?max_fd=1;//int?max_fd=fds[0].fd63?????int?_timeout=5000;64?????fds[0].fd=listen_sock;//why?locate65?????fds[0].events=POLLIN;66?????fds[0].revents=0;67?68?????size_t?i=1;69?????for(;i<_NUM_;i++)70?????{71?????????fds[i].fd=-1;72?????????fds[i].events=0;73?????????fds[i].revents=0;74?????}75?????while(1)76?????{77?????????switch(poll(fds,max_fd,_timeout))78?????????{79?????????????case?-1:80?????????????????perror("poll");81?????????????????break;82?????????????case?0:83?????????????????printf("timeout...\n");84?????????????????break;85?????????????default:86?????????????????{87?????????????????????i=0;88?????????????????????for(;i<_NUM_;++i)89?????????????????????{90?????????????????????????if((fds[i].fd==listen_sock)&&(fds[i].revents==POLLIN????))91?????????????????????????{92?????????????????????????????int?new_sock=accept(listen_sock,(struct?sockaddr????*)&client,&len);93?????????????????????????????if(new_sock<0)94?????????????????????????????{95?????????????????????????????????perror("accept");96?????????????????????????????????continue;97?????????????????????????????}98?????????????????????????????printf("get?a?new?connect...%d\n",new_sock);99?????????????????????????????for(i=0;i<_NUM_;i++) 100?????????????????????????????{ 101?????????????????????????????????if(fds[i].fd==-1) 102?????????????????????????????????{ 103?????????????????????????????????????fds[i].fd=new_sock; 104?????????????????????????????????????fds[i].events=POLLIN; 105?????????????????????????????????????max_fd++; 106?????????????????????????????????????break; 107?????????????????????????????????} 108?????????????????????????????} 109?????????????????????????????if(i==_NUM_) 110?????????????????????????????{ 111?????????????????????????????????close(new_sock); 112?????????????????????????????} 113?????????????????????????} 114?????????????????????????else?if((fds[i].fd>0)&&(fds[i].revents==POLLIN)) 115?????????????????????????{ 116?????????????????????????????char?buf[1024]; 117?????????????????????????????ssize_t?_s=read(fds[i].fd,buf,sizeof(buf)-1); 118?????????????????????????????if(_s>0) 119?????????????????????????????{ 120?????????????????????????????????//read?sucess 121?????????????????????????????????buf[_s]='\0'; 122?????????????????????????????????printf("client:%s\n",buf); 123?????????????????????????????} 124?????????????????????????????else?if(_s==0) 125?????????????????????????????{ 126?????????????????????????????????//client?shutdown 127?????????????????????????????????printf("client?shutdown...\n"); 128?????????????????????????????????// 129?????????????????????????????????struct?pollfd?tmp=fds[i]; 130?????????????????????????????????fds[i]=fds[max_fd-1]; 131?????????????????????????????????fds[max_fd-1]=tmp; 132?????????????????????????????????// 133?????????????????????????????????close(fds[max_fd-1].fd); 134?????????????????????????????????// 135? 136?????????????????????????????????fds[max_fd-1].fd=-1; 137?????????????????????????????????fds[max_fd-1].events=0; 138?????????????????????????????????fds[max_fd-1].revents=0; 139?????????????????????????????????//easy?ignore 140?????????????????????????????????--max_fd; 141?????????????????????????????} 142?????????????????????????????else 143?????????????????????????????{ 144?????????????????????????????????perror("read"); 145?????????????????????????????} 146?????????????????????????} 147?????????????????????????//normal?socket 148?????????????????????????else 149?????????????????????????{} 150?????????????????????} 151?????????????????} 152?????????????????break; 153?????????} 154?????} 155?????return?0; 156?}//poll_client.c1?#include<stdio.h>2?#include<stdlib.h>3?#include<string.h>4?#include<sys/types.h>5?#include<sys/socket.h>6?#include<netinet/in.h>7?#include<arpa/inet.h>8?#include<unistd.h>9?10?void?usage(const?char*?proc)11?{???12?????printf("%s?[ip]?[port]\n",proc);13?????exit(1);14?}15?int?main(int?argc,char*?argv[])16?{17?????if(argc!=3)18?????{19?????????usage(argv[0]);20?????????exit(1);21?????}22?????int?server_ip=inet_addr(argv[1]);23?????int?server_port=atoi(argv[2]);24?25?????int?client_sock=socket(AF_INET,SOCK_STREAM,0);26?????if(client_sock<0)27?????{28?????????perror("socket");29?????????exit(2);30?????}31?????struct?sockaddr_in?server;32?????server.sin_family=AF_INET;33?????server.sin_addr.s_addr=server_ip;34?????server.sin_port=htons(server_port);35?36?????if(connect(client_sock,(struct?sockaddr*)&server,sizeof(server))<0)37?????{38?????????perror("connect");39?????????exit(3);40?????}41?????char?buf[1024];42?????while(1)43?????{44?????????memset(buf,'\0',sizeof(buf));45?????????printf("Please?Input:?");46?????????fflush(stdout);47?????????fgets(buf,sizeof(buf)-1,stdin);48?????????if(send(client_sock,buf,sizeof(buf)-1,0)<0)49?????????{50?????????????perror("send");51?????????????continue;52?????????}53?????????ssize_t?_size=recv(client_sock,buf,sizeof(buf)-1,0);54?????????if(_size>0)55?????????{56?????????????buf[_size]='\0';57?????????????printf("server?receive:%s\n",buf);58?????????}59?????}60?????return?0;61?}//makefile1?.PHONY:all2?all:poll_server?poll_client3?poll_server:poll_server.c4?????gcc?-o?$@?$^5?poll_client:poll_client.c6?????gcc?-o?$@?$^7?.PHONY:clean8?clean:9?????rm?-f?poll_server?poll_client//start.sh1?#!/bin/bash2?3?service?iptables?stop4?./poll_server?192.168.163.128?8080

    運行結果:

    轉載于:https://blog.51cto.com/10707460/1794320

    總結

    以上是生活随笔為你收集整理的I/O多路转接之poll——基于TCP协议的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。