中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux 高級I/O之poll函數及簡單服務器客戶端編程

發布時間:2020-02-27 03:30:12 來源:網絡 閱讀:791 作者:昵稱真難改 欄目:系統運維

當需要同時監聽多個文件描述符時,就需要I/O復用函數,I/O復用函數有select、poll、epoll,今天主要使用poll函數。

poll()接受一個指向結構'struct pollfd'列表的指針,其中包括了你想測試的文件描述符和事件。事件由一個在結構中事件域的比特掩碼確定。當前的結構在調用后將被填寫并在事件發生后返回。

函數原型:

#include<poll.h>
int?poll(struct?pollfd?*fds,?nfds_t?nfds,?int?timeout);
struct?pollfd{
????int?fd;?????????/*file?descriptor*/
????short?events;???/*requested?events*/
????short?revents;??/*returned?events*/
}

函數參數:fds是要監聽的fd的數組,nfds是數組個數,timeout 超時時間 -1是阻塞;

函數說用:通過傳入的events的類型去判斷返回的類型是否一致,如果一致就該干事了。

events:


常量

說明

POLLIN

普通或優先級帶數據可讀

POLLRDNORM

普通數據可讀

POLLRDBAND

優先級帶數據可讀

POLLPRI

高優先級數據可讀

POLLOUT

普通數據可寫

POLLWRNORM

普通數據可寫

POLLWRBAND

優先級帶數據可寫

POLLERR

發生錯誤

POLLHUP

發生掛起

POLLNVAL

描述字不是一個打開的文件


接下來是是一個服務器監聽兩個socket的例子:

服務器代碼:

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

#define?MAX_POLLFD_NUM?2
//#define?SERVER_CONN_IP1?"1.1.1.1"
//#define?SERVER_CONN_IP2?"1.1.1.1"
#define?DEFAULT_PORT?8000
#define?BUFF_MAX?1024

typedef?void(*Server_Rrocess_Thread_Fun)(void?*arg);
/*thread?process?function?define?*/
typedef?struct?sever_thread_fun{
	Server_Rrocess_Thread_Fun?Server_Process_Client_Conn1;
	Server_Rrocess_Thread_Fun?Server_Process_Client_Conn2;
}Poll_Server_Process_Clinet_FUN_t;
/*connect?1?thread?function*/
void?*Poll_Conn1_Process(void?*arg)
{
	unsigned?char?ucBufArr[BUFF_MAX]?=?{0};
	unsigned?long?ulSize?=?0;
	int?connect_fd?;
????printf("come?pthread?conn1?fun?to?proess?conn1\n");
	if(?(connect_fd?=?accept(?*(int*)arg,?(struct?sockaddr*)NULL,?NULL))?==?-1){??
		printf("accept?socket?error:?%s(errno:?%d)",strerror(errno),errno);??
????}
	ulSize?=?recv(connect_fd,?ucBufArr,?BUFF_MAX,?0);??

	if(send(connect_fd,?"Hello,you?are?connected?1!\n",?26,0)?==?-1)??
	perror("send?error");??
	ucBufArr[ulSize]?=?'\0';??
????//sleep(20);
	printf("recv?msg?from?client:?%s\n",?ucBufArr);??
	close(connect_fd);??
	pthread_exit((void*)1);
}
/*connect?1?thread?function*/
void?*Poll_Conn2_Process(void?*arg)
{
	unsigned?char?ucBufArr[BUFF_MAX]?=?{0};
	unsigned?long?ulSize?=?0;	
	int?connect_fd?;
????printf("come?pthread?conn2?fun?to?proess?conn2\n");
	if(?(connect_fd?=?accept(?*(int*)arg,?(struct?sockaddr*)NULL,?NULL))?==?-1){??
		printf("accept?socket?error:?%s(errno:?%d)",strerror(errno),errno);??
????}
	ulSize?=?recv(connect_fd,?ucBufArr,?BUFF_MAX,?0);??

	if(send(connect_fd,?"Hello,you?are?connected?2!\n",?26,0)?==?-1)??
	perror("send?error");??
	ucBufArr[ulSize]?=?'\0';??
???//?sleep(20);
	printf("recv?msg?from?client:?%s\n",?ucBufArr);??
	close(connect_fd);??
	pthread_exit((void*)2);
}
int?main()
{	
????int?poll_ret?=?0;
	pthread_t?thread_conn1;
	pthread_t?thread_conn2;
????/*socket?var*/
	int?server_socket_fd_conn1;
	int?server_socket_fd_conn2;
	struct?sockaddr_in?servaddr_conn1;
	struct?sockaddr_in?serveraddr_conn2;
	/*poll?var*/
????struct?pollfd?pollfd_arr[MAX_POLLFD_NUM];
	/*init?thread?fun*/
	Poll_Server_Process_Clinet_FUN_t?server_conn_handel;
	server_conn_handel.Server_Process_Client_Conn1?=?Poll_Conn1_Process;
	server_conn_handel.Server_Process_Client_Conn2?=?Poll_Conn2_Process;
	/*create?two?server?socket*/
	if(?(server_socket_fd_conn1?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1?){??
????printf("create?socket?conn1?error:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	if(?(server_socket_fd_conn2?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1?){??
????printf("create?socket?conn2?error:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	
????/*init?socket?1?for?conn1*/??
????memset(&servaddr_conn1,?0,?sizeof(servaddr_conn1));??
????servaddr_conn1.sin_family?=?AF_INET;??	
????servaddr_conn1.sin_addr.s_addr?=?htonl(INADDR_ANY);?
????servaddr_conn1.sin_port?=?htons(DEFAULT_PORT);?
//	if(?inet_pton(AF_INET,?SERVER_CONN_IP1,?&servaddr_conn1.sin_addr.s_addr)?<=?0){??
?//???printf("inet_pton?error?for?%s\n",SERVER_CONN_IP1);??
??//??exit(0);??
???//?}??
	/*init?socket?2?for?conn2*/??
	memset(&serveraddr_conn2,?0,?sizeof(serveraddr_conn2));??
????serveraddr_conn2.sin_family?=?AF_INET;??
????serveraddr_conn2.sin_addr.s_addr?=?htonl(INADDR_ANY);?
????serveraddr_conn2.sin_port?=?htons(DEFAULT_PORT+1);?
//	if(?inet_pton(AF_INET,?SERVER_CONN_IP2,?&serveraddr_conn2.sin_addr.s_addr)?<=?0){??
?//???printf("inet_pton?error?for?%s\n",SERVER_CONN_IP2);??
??//??exit(0);??
???//?}??
??
????/*bind?connect?1?socket*/
????if(?bind(server_socket_fd_conn1,?(struct?sockaddr*)&servaddr_conn1,?sizeof(servaddr_conn1))?==?-1){??
????printf("bind?socket?error1:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	/*bind?connect?2?socket*/
	if(?bind(server_socket_fd_conn2,?(struct?sockaddr*)&serveraddr_conn2,?sizeof(serveraddr_conn2))?==?-1){??
????printf("bind?socket?error2:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
????/*listen?connect?1*/??
????if(?listen(server_socket_fd_conn1,?10)?==?-1){??
????printf("listen?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	/*listen?connect?2*/??
????if(?listen(server_socket_fd_conn2,?10)?==?-1){??
????printf("listen?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	pollfd_arr[0].events?=?POLLRDNORM;/*only?read?event*/
	pollfd_arr[0].fd?=?server_socket_fd_conn1;
	
	pollfd_arr[1].events?=?POLLRDNORM;/*only?read?event*/
	pollfd_arr[1].fd?=?server_socket_fd_conn2;
????while(1)
	{
		poll_ret?=?poll(?pollfd_arr,?MAX_POLLFD_NUM,-1);
		if(?pollfd_arr[0].revents?&?POLLRDNORM?)
		{
			/*connect?1?process?task*/
			pthread_create(?&thread_conn1,?NULL,?server_conn_handel.Server_Process_Client_Conn1,?(void?*)(&pollfd_arr[0].fd));
		}
		if(?pollfd_arr[1].revents?&?POLLRDNORM?)
		{
			/*connect?2?process?task*/
			pthread_create(?&thread_conn2,?NULL,?server_conn_handel.Server_Process_Client_Conn2,?(void?*)(&pollfd_arr[1].fd));
		}
		sleep(1);
	}
	return?0;
}

客戶端代碼:

#include<stdio.h>??
#include<stdlib.h>??
#include<string.h>??
#include<errno.h>??
#include<sys/types.h>??
#include<sys/socket.h>??
#include<netinet/in.h>??
??
#define?BUFF_MAX?1024
#define?DEFAULT_PORT?8000
int?main(int?argc,?char**?argv)??
{??
????int????sockfd,?n,rec_len;??
????char????recvline[BUFF_MAX],?sendline[BUFF_MAX];??
????char????buf[BUFF_MAX];??
????struct?sockaddr_in????servaddr;??
??
??
????if(?argc?!=?2){??
????printf("usage:?./client?<ipaddress>\n");??
????exit(0);??
????}??
??
????/*create?socket*/
????if(?(sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?<?0){??
????printf("create?socket?error:?%s(errno:?%d)\n",?strerror(errno),errno);??
????exit(0);??
????}??
	
????memset(&servaddr,?0,?sizeof(servaddr));??
????servaddr.sin_family?=?AF_INET;??
????servaddr.sin_port?=?htons(DEFAULT_PORT/*+1/);/*DEFAULT_PORT?is?connect?1?to?server,DEFAULT_PORT+1?is?connect?2?to?server*/??
	/*string?ip?to?int?ip*/
????if(?inet_pton(AF_INET,?argv[1],?&servaddr.sin_addr)?<=?0){??
????printf("inet_pton?error?for?%s\n",argv[1]);??
????exit(0);??
????}??
????/*connect?server*/
????if(?connect(sockfd,?(struct?sockaddr*)&servaddr,?sizeof(servaddr))?<?0){??
????printf("connect?error:?%s(errno:?%d)\n",strerror(errno),errno);??
????exit(0);??
????}??
	
????printf("send?msg?to?server:?\n");??
????fgets(sendline,?BUFF_MAX,?stdin);??
	/*write?data?to?sockfd*/
????if(?send(sockfd,?sendline,?strlen(sendline),?0)?<?0)??
????{??
????printf("send?msg?error:?%s(errno:?%d)\n",?strerror(errno),?errno);??
????exit(0);??
????}??
	/*read?socket?data*/
????if((rec_len?=?recv(sockfd,?buf,?BUFF_MAX,0))?==?-1)?{??
???????perror("recv?error");??
???????exit(1);??
????}??
????buf[rec_len]??=?'\0';??
????printf("Received?:?%s?\n",buf);??
	/*colse?socket*/
????close(sockfd);??
????exit(0);??
}

解釋:服務器端監聽 ip 127.0.0.1 port 8000和ip 127.0.0.1 port 8001

結果演示:

Linux 高級I/O之poll函數及簡單服務器客戶端編程


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潜山县| 六盘水市| 科技| 平原县| 鸡东县| 滦平县| 柏乡县| 通道| 昔阳县| 定州市| 双桥区| 泽州县| 阿克陶县| 石城县| 深水埗区| 枣庄市| 梁平县| 建瓯市| 台南县| 平阴县| 忻城县| 区。| 吐鲁番市| 康平县| 鸡东县| 河津市| 平遥县| 涿鹿县| 怀来县| 元江| 车致| 兴仁县| 自治县| 绥宁县| 巫溪县| 祁东县| 金寨县| 博野县| 久治县| 茶陵县| 松原市|