国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

IO多路復(fù)用中select的TCP服務(wù)器模型和poll服務(wù)模型

這篇具有很好參考價值的文章主要介紹了IO多路復(fù)用中select的TCP服務(wù)器模型和poll服務(wù)模型。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

select的TCP服務(wù)器模型

服務(wù)器端

#include <head.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>


#define PORT 6666   //1024~49151
#define IP "192.168.122.120"  //ifconfig查看本機(jī)IP
int main(int argc, const char *argv[])
{
	//創(chuàng)建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd < 0)
	{
		ERRO_MES("socket");
		return -1;
	}
	printf("sfd = %d\n",sfd);
	//綁定服務(wù)器的IP和端口--->必須綁定
	//填充地址信息結(jié)構(gòu)體,真實的地址信息結(jié)構(gòu)體根據(jù)地質(zhì)族制定
	//AF_INET: man 7 ip;
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//必須填A(yù)F_INET;
	sin.sin_port = htons(PORT);  //端口號:1024~49151;
	sin.sin_addr.s_addr = inet_addr(IP);  //本機(jī)IP ifconfig查看;
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
	{
		ERRO_MES("bind");
		return -1;
	}
	printf("bind success\n");
	//將套接字設(shè)置為被動監(jiān)聽狀態(tài)
	if(listen(sfd,10) < 0)
	{
		ERRO_MES("listen");
		return -1;
	}
	printf("listen success\n");
	//設(shè)置允許端口號被快速復(fù)用
	int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERRO_MES("setsockopt");
        return -1;
    }
    printf("允許端口快速重用成功\n");
	//從已完成鏈接的隊列中獲取一個客戶端信息,生成一個新的文件
	//該文件描述符才是與客戶端通信的文件描述符
	struct sockaddr_in cin;
	socklen_t addrlen = sizeof(cin);

	struct sockaddr_in saveCin[1024-3];
	//創(chuàng)建一個讀集合
	fd_set readfds,tempfds;
	
	//初始化文件描述符
	FD_ZERO(&readfds);
	FD_ZERO(&tempfds);
	//將需要的文件描述符添加到讀集合中
	
	FD_SET(sfd,&readfds);
	FD_SET(0,&readfds);

	//確定最大文件描述符
	int	maxfd = sfd;
	int s_res = -1;
	char buf[128]="";
	ssize_t res = 0;
	int newfd = -1;
	while(1)
	{
		tempfds = readfds;
		//調(diào)用IO多路復(fù)用函數(shù) ,select()
		s_res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
		if(s_res < 0)
		{
			ERRO_MES("select");
			return -1;
		}
		else if(0 == s_res)
		{
			printf("超時操作\n");
			break;
		}
		//判斷是哪個文件描述符準(zhǔn)備就緒,走對應(yīng)處理函數(shù)即可
		for(int i=0; i<=maxfd; i++)
		{
			if(FD_ISSET(i, &tempfds) == 0)
				continue;
			if(0 == i)
		{
			printf("觸發(fā)鍵盤輸入事件\n");
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1] = 0;
			printf(": %s\n",buf);
		}
		else if(sfd == i)
		{
			printf("觸發(fā)客戶端連接事件\n");

			newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
			if(newfd < 0)
			{
				ERRO_MES("accept");
				return -1;
			}
			printf("[%s : %d]  newfd = %d,客戶端鏈接成功\n",\
					inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);
			saveCin[newfd-3] = cin;
			//將newfd添加到集合
			FD_SET(newfd, &readfds);

			maxfd = newfd>sfd ? newfd : sfd;

		}
		else
		{
				printf("觸發(fā)客戶端交互事件\n");
				bzero(buf,sizeof(buf));
				//接收數(shù)據(jù)
				res = recv(i,buf,sizeof(buf),0);
				if(res < 0)
				{
					ERRO_MES("recv");
					return -1;
				}
				else if(0 == res)
				{
					printf("[%s : %d]  newfd = %d,客戶下線\n",\
							inet_ntoa(saveCin[i-3].sin_addr),ntohs(saveCin[i-3].sin_port),i);
					//關(guān)閉下線客戶端的文件描述符
					close(i);
					//將下線客戶端的文件描述符從集合中剔除
					FD_CLR(i,&readfds);
					//更新maxfd
					while(FD_ISSET(maxfd,&readfds) == 0 && maxfd-- >=0);
					continue;
				}
				printf("[%s : %d]  newfd :%d\t buf = %s\n"\
						,inet_ntoa(saveCin[i-3].sin_addr),ntohs(saveCin[i-3].sin_port),i,buf);
				//發(fā)送數(shù)據(jù)
				strcat(buf,"----");
				if(send(newfd,buf,sizeof(buf),0) < 0)
				{
					ERRO_MES("send");
					return -1;
				}
				printf("send success\n");


		}
		}
	}

	close(sfd);
	close(newfd);

	return 0;
}

客戶端

#include <head.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h> 
#include <sys/select.h>
#include <sys/time.h>

#define PORT 6666   //1024~49151
#define IP "192.168.122.120"  //ifconfig查看本機(jī)IP
int main(int argc, const char *argv[])
{
	//創(chuàng)建流式套接字
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd < 0)
	{
		ERRO_MES("socket");
		return -1;
	}
	printf("cfd = %d\n",cfd);

	//綁定服務(wù)器的IP和端口--->非必須綁定
	//填充地址信息結(jié)構(gòu)體,真實的地址信息結(jié)構(gòu)體根據(jù)地質(zhì)族制定
	//AF_INET: man 7 ip;
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//必須填A(yù)F_INET;
	sin.sin_port = htons(PORT);  //端口號:填服務(wù)器綁定的端口號;
	sin.sin_addr.s_addr = inet_addr(IP);//IP地址;服務(wù)器綁定的IP地址

	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
	{
		ERRO_MES("connect");
		return -1;
	}
	printf("連接成功\n");
	
	//創(chuàng)建一個讀集合
	fd_set readfds,tempfds;

	//初始化集合
	FD_ZERO(&readfds);
	FD_ZERO(&tempfds);

	//將需要的文件描述符添加到讀集合
	FD_SET(0,&readfds);
	FD_SET(cfd,&readfds);

	char buf[128]="";
	ssize_t res = 0;
	int s_res = -1;
	int maxfd = cfd;

	while(1)
	{
		tempfds = readfds;
		s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);
		if(s_res < 0)
		{
			ERRO_MES("select");
			return -1;
		}
		else if(0 == s_res)
		{
			printf("time out...\n");
			break;
		}
		if(FD_ISSET(0,&tempfds))
		{
			printf("觸發(fā)鍵盤輸入事件\n");
			bzero(buf,sizeof(buf));
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1] = 0;
			printf(": %s\n",buf);
			if(send(cfd,buf,sizeof(buf),0) < 0)
			{
				ERRO_MES("send");
				return -1;
			}
			printf("send success\n");
		}

		if(FD_ISSET(cfd,&tempfds))
		{
			printf("觸發(fā)服務(wù)器交互事件\n");
			bzero(buf,sizeof(buf));
			//接收數(shù)據(jù)
			res = recv(cfd,buf,sizeof(buf),0);
			if(res < 0)
			{
				ERRO_MES("recv");
				return -1;
			}
			else if(0 == res)
			{
				printf("[%s : %d]  cfd = %d,客戶下線\n",IP,PORT,cfd);
				break;
			}
			printf("[%s : %d]  cfd :%d\t buf = %s\n",IP,PORT,cfd,buf);
			}
	}
	close(cfd);
	return 0;
}

poll客戶端

#include <head.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>
#include <unistd.h>

#define PORT 6666
#define IP "192.168.122.120"
int main(int argc, const char *argv[])
{
	//創(chuàng)建流式套接字
	int cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd < 0)
	{
		ERRO_MES("socket");
		return -1;
	}
	printf("cfd = %d\n",cfd);
	
	//綁定客戶端的IP和端口 ----->客戶端(非必須)
	//若不綁定,則操作系統(tǒng)會給客戶端綁定上客戶端所在的主機(jī)IP,以及隨機(jī)端口(49152~65535)
	

	//填充服務(wù)器的地址信息結(jié)構(gòu)體,真實的地址信息結(jié)構(gòu)體根據(jù)地址族指定
	//AF_INET:man 7 ip
	//要連接哪個服務(wù)器,就填對應(yīng)服務(wù)器的IP和端口
	struct sockaddr_in sin;
	sin.sin_family 		= AF_INET; //必須填A(yù)F_INET
	sin.sin_port 		= htons(PORT); //端口號:填服務(wù)器綁定端口號
	sin.sin_addr.s_addr = inet_addr(IP); //IP地址:服務(wù)器綁定的IP地址

	//連接服務(wù)器
	if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) < 0)
	{
		ERRO_MES("connect");
		return -1;
	}
	printf("connect success\n");

	//定義集合
	struct pollfd fds[2];

	//將需要監(jiān)測的文件描述符添加到集合中
	fds[0].fd = 0;  				//指定監(jiān)測0號文件描述符
	fds[0].events = POLLIN; 		//監(jiān)測讀事件

	fds[1].fd = cfd; 				//指定監(jiān)測cfd號文件描述符
	fds[1].events = POLLIN; 		//監(jiān)測讀事件

	char buf[128] = "";
	ssize_t res = 0;
	int p_res = -1;

	while(1)
	{
		p_res = poll(fds,2,-1);
		if(p_res < 0)
		{
			ERRO_MES("poll");
			return -1;
		}
		else if(0 == p_res)
		{
			printf("time out...\n");
			break;
		}
		//能運(yùn)行到當(dāng)前位置,代表集合中有文件描述符準(zhǔn)備就緒
		//判斷是哪個文件描述符準(zhǔn)備就緒,走對應(yīng)處理函數(shù)
		//判斷集合中的每個文件描述符的revents中是否有POLLIN
		//從revents中將代表POLLIN的那一位單獨(dú)提取出來,判斷是1還是0

		if((fds[0].revents & POLLIN) != 0)
		{
			printf("觸發(fā)鍵盤輸入事件\n");
			bzero(buf,sizeof(buf));
			fgets(buf,sizeof(buf),stdin);
			buf[strlen(buf)-1] = 0;

			//發(fā)送數(shù)據(jù)
			if(send(cfd, buf,sizeof(buf),0) < 0)
			{
				ERRO_MES("send");
				return -1;
			}
			printf("send success\n");
		}

		if(fds[1].revents & POLLIN)
		{
			printf("觸發(fā)服務(wù)器交互事件\n");
			bzero(buf,sizeof(buf));
			//接收數(shù)據(jù)
			res = recv(cfd,buf,sizeof(buf),0);
			if(res < 0)
			{
				ERRO_MES("recv");
				return -1;
			}
			else if(0 == res)
			{
				printf("[%s : %d] cfd= %d  服務(wù)器掉線\n",IP,PORT,cfd);
				break;
			}
			printf("[%s : %d] cfd= %d : %s\n",IP,PORT,cfd,buf);
		}
	}
	close(cfd);
	return 0;
}

文章來源地址http://www.zghlxwxcb.cn/news/detail-650162.html

到了這里,關(guān)于IO多路復(fù)用中select的TCP服務(wù)器模型和poll服務(wù)模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 多路轉(zhuǎn)接高性能IO服務(wù)器|select|poll|epoll|模型詳細(xì)實現(xiàn)

    多路轉(zhuǎn)接高性能IO服務(wù)器|select|poll|epoll|模型詳細(xì)實現(xiàn)

    那么這里博主先安利一下一些干貨滿滿的專欄啦! Linux專欄 https://blog.csdn.net/yu_cblog/category_11786077.html?spm=1001.2014.3001.5482 操作系統(tǒng)專欄 https://blog.csdn.net/yu_cblog/category_12165502.html?spm=1001.2014.3001.5482 手撕數(shù)據(jù)結(jié)構(gòu) https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014.3001.5482 去倉庫獲

    2024年02月15日
    瀏覽(25)
  • 【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】引入IO多路復(fù)用(select,poll,epoll)實現(xiàn)高并發(fā)tcp服務(wù)端

    【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】引入IO多路復(fù)用(select,poll,epoll)實現(xiàn)高并發(fā)tcp服務(wù)端

    目錄 一,往期文章 二,基本概念 IO多路復(fù)用 select 模型 poll 模型 epoll 模型 select,poll,epoll 三者對比 三,函數(shù)清單 1.select 方法 2.fd_set 結(jié)構(gòu)體 3.poll 方法 4.struct pollfd 結(jié)構(gòu)體 5.epoll_create 方法 6.epoll_ctl 方法 7.epoll_wait 方法 8.struct epoll_event 結(jié)構(gòu)體 四,代碼實現(xiàn) select 操作流程 s

    2024年02月12日
    瀏覽(31)
  • 【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】3.引入IO多路復(fù)用(select,poll,epoll)實現(xiàn)高并發(fā)tcp服務(wù)端

    【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】3.引入IO多路復(fù)用(select,poll,epoll)實現(xiàn)高并發(fā)tcp服務(wù)端

    目錄 一,往期文章 二,基本概念 IO多路復(fù)用 select 模型 poll 模型 epoll 模型 select,poll,epoll 三者對比 三,函數(shù)清單 1.select 方法 2.fd_set 結(jié)構(gòu)體 3.poll 方法 4.struct pollfd 結(jié)構(gòu)體 5.epoll_create 方法 6.epoll_ctl 方法 7.epoll_wait 方法 8.struct epoll_event 結(jié)構(gòu)體 四,代碼實現(xiàn) select 操作流程 s

    2024年02月14日
    瀏覽(26)
  • linux并發(fā)服務(wù)器 —— IO多路復(fù)用(八)

    linux并發(fā)服務(wù)器 —— IO多路復(fù)用(八)

    半關(guān)閉只能實現(xiàn)數(shù)據(jù)單方向的傳輸;當(dāng)TCP 接中A向 B 發(fā)送 FIN 請求關(guān)閉,另一端 B 回應(yīng)ACK 之后 (A 端進(jìn)入 FIN_WAIT_2 狀態(tài)),并沒有立即發(fā)送 FIN 給 A,A 方處于半連接狀態(tài) (半開關(guān)),此時 A 可以接收 B 發(fā)送的數(shù)據(jù),但是 A 已經(jīng)不能再向 B 發(fā)送數(shù)據(jù) close不會影響到其他進(jìn)程,shutdown會

    2024年02月09日
    瀏覽(22)
  • 【高并發(fā)服務(wù)器 02】——線程池與IO多路復(fù)用

    線程池的好處 :所有的池都是為了事先把資源準(zhǔn)備好,在后續(xù)用的時候可以更加方便的拿到這個資源—— 不用去申請、釋放資源 什么時候用線程池 ? IO事務(wù)并發(fā)較高 :人在杭州,但是數(shù)據(jù)庫在北京,想要查詢數(shù)據(jù)庫,需要通過互聯(lián)網(wǎng)建立TCP三次握手,頻繁地創(chuàng)建和銷毀線

    2024年03月23日
    瀏覽(24)
  • 網(wǎng)絡(luò)編程 IO多路復(fù)用 [select版] (TCP網(wǎng)絡(luò)聊天室)

    網(wǎng)絡(luò)編程 IO多路復(fù)用 [select版] (TCP網(wǎng)絡(luò)聊天室)

    //head.h? ? ? ? ? ? ? ? ?頭文件 //TcpGrpSer.c? ? ? ? 服務(wù)器端 //TcpGrpUsr.c? ? ? ? 客戶端 select函數(shù)? 功能:阻塞函數(shù),讓內(nèi)核去監(jiān)測集合中的文件描述符是否準(zhǔn)備就緒,若準(zhǔn)備就緒則解除阻塞。 原型: head.h TcpGrpSer.c TcpGrpUsr.c ? ?

    2024年02月14日
    瀏覽(25)
  • Linux多路IO復(fù)用技術(shù)——epoll詳解與一對多服務(wù)器實現(xiàn)

    Linux多路IO復(fù)用技術(shù)——epoll詳解與一對多服務(wù)器實現(xiàn)

    本文詳細(xì)介紹了Linux中epoll模型的優(yōu)化原理和使用方法,以及如何利用epoll模型實現(xiàn)簡易的一對多服務(wù)器。通過對epoll模型的優(yōu)化和相關(guān)接口的解釋,幫助讀者理解epoll模型的工作原理和優(yōu)缺點(diǎn),同時附帶代碼實現(xiàn)和圖解說明。

    2024年02月05日
    瀏覽(27)
  • 【TCP/IP】利用I/O復(fù)用技術(shù)實現(xiàn)并發(fā)服務(wù)器 - select函數(shù)

    【TCP/IP】利用I/O復(fù)用技術(shù)實現(xiàn)并發(fā)服務(wù)器 - select函數(shù)

    目錄 I/O復(fù)用技術(shù) select函數(shù) 設(shè)置文件描述符 指定監(jiān)視范圍 設(shè)置超時 I/O復(fù)用服務(wù)器端的實現(xiàn) ?????? 由服務(wù)器創(chuàng)建多個進(jìn)程來實現(xiàn)并發(fā)的做法有時會帶來一些問題,比如:內(nèi)存上的開銷、CPU的大量占用等,這些因素會消耗掉服務(wù)器端有限的計算資源、進(jìn)而影響程序之間的執(zhí)

    2024年02月08日
    瀏覽(21)
  • IO多路復(fù)用之select/poll/epoll

    IO多路復(fù)用之select/poll/epoll

    掌握select編程模型,能夠?qū)崿F(xiàn)select版本的TCP服務(wù)器. 掌握poll編程模型,能夠?qū)崿F(xiàn)poll版本的TCP服務(wù)器. 掌握epoll的編程模型,能夠?qū)崿F(xiàn)epoll版本的TCP服務(wù)器. epoll的LT模式和ET模式. 理解select和epoll的優(yōu)缺點(diǎn)對比. 提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 多路轉(zhuǎn)接天然的是讓我

    2023年04月09日
    瀏覽(20)
  • 使用select實現(xiàn)TCP并發(fā)服務(wù)器模型

    使用select實現(xiàn)TCP并發(fā)服務(wù)器模型

    本期主要分享的是對于select的使用,使用select實現(xiàn)TCP并發(fā)服務(wù)器模型,由于之前所用到的技術(shù)知識只能夠支撐我們進(jìn)行單個訪問,但是有了select之后呢,我們就能夠?qū)崿F(xiàn)多用戶進(jìn)行訪問;這也是非常符合客觀需求的; 這次呢我們重點(diǎn)來使用一下select; 用到的頭文件如下: 我

    2024年02月08日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包