欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

socket編程中poll怎么使用-創(chuàng)新互聯(lián)

這篇文章主要介紹“socket編程中poll怎么使用”,在日常操作中,相信很多人在socket編程中poll怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”socket編程中poll怎么使用”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)公司,為您提供網(wǎng)站建設(shè)公司成都網(wǎng)站制作、網(wǎng)站營(yíng)銷推廣、網(wǎng)站開發(fā)設(shè)計(jì),對(duì)服務(wù)成都公路鉆孔機(jī)等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)及推廣經(jīng)驗(yàn)。創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)公司成立于2013年,提供專業(yè)網(wǎng)站制作報(bào)價(jià)服務(wù),我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞心悅目的作品。 與客戶共同發(fā)展進(jìn)步,是我們永遠(yuǎn)的責(zé)任!

一. 關(guān)于poll

  對(duì)于IO復(fù)用模型,其優(yōu)點(diǎn)無疑是免去了對(duì)一個(gè)個(gè)IO事件就緒的等待,轉(zhuǎn)而代之的是同時(shí)對(duì)多個(gè)IO數(shù)據(jù)的檢測(cè),當(dāng)檢測(cè)等待的事件中至少有一個(gè)就緒的時(shí)候,就會(huì)返回告訴用戶進(jìn)程“已經(jīng)有數(shù)據(jù)準(zhǔn)備好了,快看看是哪個(gè)趕緊處理”,而對(duì)于IO復(fù)用的實(shí)現(xiàn),除了可以用select函數(shù),另外一個(gè)函數(shù)仍然支持這種復(fù)用IO模型,就是poll函數(shù);


二. poll函數(shù)的用法

  雖然同樣是對(duì)多個(gè)IO事件進(jìn)行檢測(cè)等待,但poll和select多少還是有些不同的:

socket編程中poll怎么使用

函數(shù)參數(shù)中,

先來說nfds,這個(gè)是指當(dāng)前需要關(guān)心的文件描述符的個(gè)數(shù);

timeout同樣是設(shè)置超時(shí)時(shí)間,只是和select的timeout是一個(gè)結(jié)構(gòu)體不一樣,這里只是一個(gè)整型類型,且含義是毫秒

fds是一個(gè)結(jié)構(gòu)體指針,如下:

socket編程中poll怎么使用

結(jié)構(gòu)體中,


fd表示所要關(guān)心的文件描述符;

events表示該文件描述符所關(guān)心的事件,這是一個(gè)輸入型參數(shù),要告訴操作系統(tǒng)這個(gè)文件描述符對(duì)應(yīng)的事件所關(guān)心的操作事件是什么,比如讀或?qū)懀?/p>

revents是一個(gè)輸出型參數(shù),表示當(dāng)poll返回時(shí)告訴用戶什么操作事件是就緒的,比如如果POLLIN是就緒的,那么返回時(shí)revent的值就是POLLIN,告訴用戶fd事件的POLLIN是就緒的;

events和revents的值可以為如下:

socket編程中poll怎么使用

選項(xiàng)其實(shí)不止這三個(gè),只是這里的討論中這三個(gè)選項(xiàng)是最常用的;

events設(shè)置為POLLIN表示fd所需要讀取數(shù)據(jù),而revents若返回POLLIN則表示data已經(jīng)ready可以讀取了;

同樣,events設(shè)置為POLLOUT表示fd所關(guān)心數(shù)據(jù)的寫入,而revents返回POLLOUT則表示寫事件就緒可以進(jìn)行數(shù)據(jù)的寫入;

至于POLLPRI,后面的解釋是作為緊急選項(xiàng)來設(shè)置的,在TCP協(xié)議報(bào)文中有個(gè)URG的緊急指針是表示先從緊急數(shù)據(jù)的地方開始讀取,這里也是這個(gè)意思;

與select不同的是,reads與writes是輸入輸出參數(shù),我上一篇博客中設(shè)置中:

 else if(fds[i] > 0 &&\
                                FD_ISSET(fds[i],&reads))    //正常事件,但是是非監(jiān)聽時(shí)間,也就代表時(shí)新建立的new_sock。
                                {
                                //  char buf[1024];
                                    ssize_t s = read(fds[i],buf,sizeof(buf) -1);
                                    if(s > 0)
                                    {
                                        buf[s] = '\0';
                                    //  printf("client : %s\n",buf);
                                        printf("client : %s",buf);
                                        FD_SET(fds[i],&writes);
                                    //  write(fds[i],buf,sizeof(s)+1);
                                    }
                                    else if(s == 0)
                                    {
                                        printf("client quit...\n");
                                        close(fds[i]);
                                        fds[i] = -1;
                                    }
                                    else{}
                                }
                        else{}
 
                        if(fds[i] > 0&&\
                                FD_ISSET(fds[i],&writes))
                        {
                            write(fds[i],buf,sizeof(buf));
                        }

在獲取讀事件時(shí)對(duì)將fds[i],設(shè)置到寫事件中,而在poll中,讀事件判斷中修改設(shè)置為寫事件。需要等待下一次循環(huán),才能夠獲取到寫事件,然后還必須將events屬性在設(shè)置回來。

poll與select不同在于描述符存儲(chǔ)方式不同和參數(shù)類型不同。

1.結(jié)構(gòu)體數(shù)組的管理:當(dāng)每次有需要關(guān)心的描述符時(shí),將其放入結(jié)構(gòu)體中,每次有無效的描述符后,將其描述符置-1,下次poll函數(shù)會(huì)忽略它。當(dāng)有新的描述符加入時(shí),從頭遍歷結(jié)構(gòu)體,將為-1的元素設(shè)為要關(guān)心的描述符事件狀態(tài)。切記:當(dāng)新的描述符加到結(jié)構(gòu)體數(shù)組末尾時(shí)要更新關(guān)心描述符個(gè)數(shù),即poll第二個(gè)參數(shù)。

2.每次調(diào)用poll后,結(jié)構(gòu)體元素revents會(huì)存儲(chǔ)就緒事件狀態(tài),當(dāng)每次重新調(diào)用poll之前時(shí),系統(tǒng)會(huì)自己設(shè)置其為0,重新監(jiān)聽關(guān)心事件(不需要用戶重新置0)

3.poll中參數(shù)不是輸入,輸出型,因此timeout,struct pollfd *fds參數(shù)不需重置,nfds看情況(參照第一點(diǎn)),而select函數(shù)是輸入輸出類型,每次調(diào)用前需重置。

下面看服務(wù)端的代碼,客戶端就不寫了:

#include<poll.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<errno.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define _BACKLOG_ 5
#define _SIZE_ 64

static void usage (const char *proc)
{
	printf("%s [ip][prot]\n",proc);
}
 
static int start(char *ip,int port)	
{
	int sock = socket(AF_INET,SOCK_STREAM,0);
	if(sock < 0)
	{
		perror("socket");
		exit(1);
	}
	
	int opt = 1;
	if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0)
	{
		perror("setsockopt");
		exit(3);
	}

	struct sockaddr_in local;
	local.sin_family = AF_INET;
	local.sin_port = htons(port);
	local.sin_addr.s_addr = inet_addr(ip);

	

	if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0)
	{
		perror("bind");
		exit(2);
	}

	if(listen(sock,_BACKLOG_) < 0)
	{
		perror("listen");
		exit(2);
	}
	return sock;
}



int main(int argc,char* argv[])
{
	if(argc != 3)
	{
		usage(argv[0]);
		return 1;
	}

	int port = atoi(argv[2]);
	char *ip = argv[1];

	int listen_sock = start(ip,port);

	//pollfd arrays
	struct pollfd polls[_SIZE_];
	int index = 0;
	int timeout = 5000; //check question time
	int i = 0;
	polls[0].fd = listen_sock;
	polls[0].events = POLLIN;
	polls[0].revents = 0;
	++index;
	//init polls.fd
	for(i = 1;i < _SIZE_;++i)
	{
		polls[i].fd = -1;
	}
	char buf [1024];
	ssize_t s = 0;
	struct sockaddr_in client;
	socklen_t len = sizeof(client);
	int done = 0;
	int max_fd = 1;
	while(!done)
	{
		switch(poll(polls,max_fd,timeout))
		{
			case -1:
				perror("poll");
				break;
			case 0:
				printf("timeout\n");
				break;
			default:
				{
					size_t i = 0;
					for(;i<_SIZE_;++i)
					{
						if((polls[i].fd == listen_sock) && (polls[i].revents == POLLIN))
						{
							int accept_sock = accept(listen_sock,(struct sockaddr*)&client,&len);
							if(accept_sock < 0)
							{
								perror("accept");
								continue;
							}
							printf("connet success\n");
							for(;i < _SIZE_;++i)
							{
								if(polls[i].fd == -1)
								{
									polls[i].fd = accept_sock;
									polls[i].events = POLLIN;
									++max_fd;
									break;
								}
							}
							if(i == _SIZE_)
							{
								close(accept_sock);
							}
						}
						else if((polls[i].fd > 0) &&(polls[i].revents == POLLIN) )
						{
							ssize_t size = read(polls[i].fd,buf,sizeof(buf)-1);
							if(size < 0)
							{
								perror("read");
								continue;
							}
							else if(size == 0)
							{
								printf("client close \n");
								struct pollfd tmp = polls[i];
								polls[i] = polls[max_fd -1];
								polls[max_fd -1] = tmp;

								close(polls[max_fd - 1].fd);
								polls[max_fd - 1].fd = -1;
							}
							else
							{
								buf[size] = '\0';
								printf("client # %s",buf);
								polls[i].events = POLLOUT;
							}
						}
						else if(polls[i].fd > 0&& \
								polls[i].revents == POLLOUT)
						{
							write(polls[i].fd,buf,sizeof(buf));
							polls[i].events = POLLIN;
						}
					}
				}
				break;
		}
	}
	return 0;
}

運(yùn)行結(jié)果:

socket編程中poll怎么使用

到此,關(guān)于“socket編程中poll怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

本文名稱:socket編程中poll怎么使用-創(chuàng)新互聯(lián)
標(biāo)題URL:http://www.chinadenli.net/article6/dgesig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google服務(wù)器托管網(wǎng)站設(shè)計(jì)響應(yīng)式網(wǎng)站搜索引擎優(yōu)化建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)