Linux下select的使用小記

來源:互聯網
上載者:User

今天使用select編程,問題很多,以前真的沒有仔細研究過。
出現了以下幾個問題
1 recvfrom在接收時,提供給系統調用的最後一個參數,用戶端的地址結構,其長度必須進行初始化,如果為0,則不能接收資料。
2 select的第一個參數為所有監視的檔案描述符的最大值+1,而不是監視的檔案描述符個數+1。
3 不要監視那些經常可用的檔案描述符,如果這樣做,select會一直返回。
4 在select返回後,如果監視的檔案描述符沒有狀態改變,則在fd_set中此檔案描述符會被清0,因此在select的迴圈中,每次進入都要重新設定我們所關注的檔案描述符。
5 如果select使用了逾時操作,每次返回select都會修改計時器,將計時器設為餘下的時間,因此如果使用了計時器,每次進入迴圈都要重設計時器。pselect沒有這個毛病。

 

下面是linux下的基於select的一個UDP反射伺服器的範例程式碼:

 

 #include <sys/select.h><br />#include <sys/types.h><br />#include <sys/time.h><br />#include <unistd.h><br />#include <stdio.h><br />#include <error.h><br />#include <stdio.h><br />#include <sys/socket.h><br />#include <arpa/inet.h><br />#include <stdlib.h><br />#include <assert.h><br />int<br />main()<br />{<br /> int sockfd = socket(AF_INET,SOCK_DGRAM,0);<br /> assert(sockfd>0);</p><p> struct sockaddr_in local;<br /> local.sin_family = AF_INET;<br /> local.sin_port = htons(8000);<br /> local.sin_addr.s_addr = INADDR_ANY;<br /> int err = bind(sockfd,(struct sockaddr*)&local,sizeof(local));<br /> assert(err==0);<br /> fd_set sets[3];<br /> for(int i=0;i<3;i++)<br /> {<br /> FD_ZERO(&sets[i]);<br /> }</p><p> timeval tv;<br /> char buf[1024];<br /> while(1)<br /> {</p><p> FD_SET(sockfd,&sets[0]);</p><p> //register<br /> tv.tv_sec = 1;<br /> //monitor and handle<br /> int nfds = select(sockfd+1,&sets[0],&sets[1],&sets[2],&tv);<br /> if(nfds<0)<br /> {<br /> perror("select");<br /> exit(-1);<br /> }<br /> printf("evnet num = %d/n",nfds);<br /> //handle<br /> for(int i=0;i<nfds;i++)<br /> {<br /> struct sockaddr_in remote;<br /> int len;<br /> socklen_t sock_len = sizeof(remote);<br /> if(FD_ISSET(sockfd,&sets[0])) //sockfd can read<br /> {<br /> len = recvfrom(sockfd,buf,1024,0,(struct sockaddr*)&remote,&sock_len);<br /> buf[len]='/0';</p><p> write(1,buf,len);<br /> printf("/n");<br /> sendto(sockfd,buf,len,0,(struct sockaddr*)&remote,sock_len);</p><p> } </p><p> }//for</p><p> }//while</p><p>}

 

 

下面是一個python的UDP反射用戶端

import socket<br />s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)<br />str = raw_input("imput your string:")<br />server = ('192.168.133.239',8000)<br />while str:<br /> s.sendto(str,server)<br /> data,server = s.recvfrom(1024)<br /> print 'recvform ',server,'data: ',data<br /> str = raw_input("imput your string:")</p><p>s.close() 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.