Linux Advanced I / O function of the poll and simple server client programming

When you need to simultaneously monitor multiple file descriptors, it is necessary I / O multiplexing function, I / O multiplexing function has select, poll, epoll, poll function is mainly used today.

poll () accepts a pointer to a structure 'struct pollfd' list of pointers , including you want to test the file descriptor and events. The event mask bit is determined by an event field in the structure. The current structure will be filled in and returned the call after the event.

Prototype:

#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*/
}

Function parameters: fds fd is to listen for an array, the array is the number of NFDs, timeout timeout -1 obstruction;

Said function with: type passed by the type of events to judge whether the return of the same, if the same relation to the Director-General.

events:

constant

Explanation

POLLIN

Normal or priority band-readable data

POLLRDNORM

Normal data read

POLLRDBAND

Priority band-readable data

POLLPRI

High priority data readable

POLLOUT

Ordinary data can be written

POLLWRNORM

Ordinary data can be written

POLLWRBAND

Priority band data can be written

POLLERR

An error occurred

POLLHUP

Hang occurs

POLLNVAL

The descriptor is not an open file


Next is a two socket server listening examples:

Server code:

#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;
}

Client code:

#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);  
}

Explanation: The server ip 127.0.0.1 port 8000 and listens ip 127.0.0.1 port 8001

The results demonstrate:

server.bmp


Guess you like

Origin blog.51cto.com/zhaoxiaohu/2429580