poll 的例子

77 篇文章 0 订阅
60 篇文章 0 订阅

server:

/*
 * Pollserver.c
 *
 *  Created on: 2012-9-9
 *      Author: sangerhoo
 */


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

#define LISTEN_QUEUE_NUM 5
#define MAX_CONNECT 1024

#define BUFFER_SIZE 256
#define ECHO_PORT 2029

static struct pollfd clipoll[MAX_CONNECT];
int max = 0;

/*initialize poll struct*/
static void poll_init()
{
	int i;
	for (i = 0; i < MAX_CONNECT; i++)
		clipoll[i].fd = -1;
}

/*
 find a unused pollfd struct
 if found then return its index
 else return -1
*/
static int poll_alloc()
{
	int i;
	for (i = 0; i < MAX_CONNECT; i++)
	{
		if (clipoll[i].fd < 0)
		return i;
	}
	return -1;
}

/*find used max index in pllfd*/
static void update_max()
{
	int i;
	max = 0;
	for (i = 0; i < MAX_CONNECT; i++)
	{
		if (clipoll[i].fd > 0)
		max = i;
	}
}

/*free a pollfd when unused*/
static int poll_free(int i)
{
	close(clipoll[i].fd);
	clipoll[i].fd = -1;
	clipoll[i].events = 0;
	clipoll[i].revents = 0;
	update_max();
}

/*
  fill up pollfd with file descriptable
  and event
*/
static int poll_set_item(int fd, uint32_t events)
{
	int i;
	if ((i = poll_alloc()) < 0)
		return -1;
	clipoll[i].fd = fd;
	clipoll[i].events = events;
	clipoll[i].revents = 0;
	if (i > max)
		max = i;
	return 0;
}

int main(int argc, char **argv)
{
	struct sockaddr_in servaddr, remote;
	int request_sock, new_sock;
	int nfound, i, bytesread;
	uint32_t addrlen;
	char buf[BUFFER_SIZE];
	/*setup socket*/
	if ((request_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		return -1;
	}
	/*fill up ip address structure*/
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = INADDR_ANY;
	servaddr.sin_port = htons(ECHO_PORT);
	/*bind server ip address structure*/
	if (bind(request_sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) <	0)
	{
		perror("bind");
		return -1;
	}
	/*listen client*/
	if (listen(request_sock, LISTEN_QUEUE_NUM) < 0)
	{
		perror("listen");
		return -1;
	}
	poll_init();
	poll_set_item(request_sock, POLLIN);
	while (1)
	{
	/*check whether ready file exist ?*/
		if ((nfound = poll(clipoll, max + 1, 500)) < 0)
		{
			if (errno == EINTR)
			{
				printf("interruptedb system call\n");
				continue;
			}
			perror("poll");
			return -1;
		}else if(nfound == 0)
		{
			printf(".");
			fflush(stdout);
			continue;
		}
		/*check listen socket if ready or not ?*/
		if (clipoll[0].revents & (POLLIN | POLLERR))
		{
			addrlen = sizeof(remote);
			if ((new_sock =	accept(request_sock, (struct sockaddr *) &remote,	&addrlen)) < 0)
			{
				perror("accept");
				return -1;
			}
			printf("connection fromm host %s,port %d, socket %d\r\n",
					inet_ntoa(remote.sin_addr), ntohs(remote.sin_port), new_sock);
			if (poll_set_item(new_sock, POLLIN) < 0)
				fprintf(stderr, "Too many connects\r\n");
			nfound--;
		}
		/*check communicating socket if ready or not ? */
		for (i = 1; i <= max && nfound > 0; i++)
		{
			if (clipoll[i].fd >= 0 && clipoll[i].revents & (POLLIN | POLLERR))
			{
				nfound--;
				if((bytesread = read(clipoll[i].fd, buf, sizeof(buf) - 1)) < 0)
				{
					perror("read");
					poll_free(i);
					continue;
				}
				if(bytesread == 0)
				{
					fprintf(stderr, "server: end of file on %d\r\n", clipoll[i].fd);
					poll_free(i);
					continue;
				}
				buf[bytesread] = 0;
				printf("%s:%d bytes from %d :%s\n", argv[0], bytesread,
				clipoll[i].fd, buf);
				if (write(clipoll[i].fd, buf, bytesread) != bytesread)
				{
					perror("echo");
					poll_free(i);
					continue;
				}
			}
		}
	}
	return 0;
}

client:

/*
 * pollclient.c
 *
 *  Created on: 2012-9-9
 *      Author: sangerhoo
 */

#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<netinet/in.h>
#include<errno.h>
#include<ctype.h>
#include<netdb.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/select.h>
#include<sys/poll.h>

#define RET_OK 0
#define RET_ERR -1
#define LISTEN_QUEUE_NUM 5

#define BUFFER_SIZE 256
#define ECHO_PORT   2029

int main(int argc, char **argv)
{
	int sock;
	struct sockaddr_in servaddr;
	struct hostent *server;
	static struct pollfd cpoll[2];
	int nfound, bytesread;
	char buf[BUFFER_SIZE];

	if(argc < 2)
	{
		fprintf(stderr, "usage %s hostname\n", argv[0]);
		return RET_ERR;
	}
	if((server = gethostbyname(argv[1])) == NULL)
	{
		perror("gethostbyname. ");
		return RET_ERR;
	}

	/*setup socket*/
	if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		return -1;
	}

	/*fillup ip address structure*/
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = *(uint32_t *) server->h_addr;
	servaddr.sin_port = htons((uint16_t) ECHO_PORT);

	/*connect to server*/
	if(connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
	{
		perror("connect");
		return -1;
	}

	/*fill up poll struct*/
	cpoll[0].fd = fileno(stdin);
	cpoll[0].events = POLLIN;
	cpoll[1].fd = sock;
	cpoll[1].events = POLLIN;

	while (1)
	{
		if ((nfound = poll(cpoll, 2, -1)) < 0)
		{
			if (errno == EINTR)
			{
			fprintf(stderr, "interruptedb system call\n");
			continue;
			}
			perror("select");
			exit(1);
		}
		/*check stdin is ready or not ? */
		if (cpoll[0].revents & (POLLIN | POLLERR))
		{
			if(fgets(buf, sizeof(buf), stdin) == NULL)
			{
				if (ferror(stdin))
				{
					perror("stdin");
					return -1;
				}
				return 0;
			}
			/*write to socket*/
			if (write(sock, buf, strlen(buf)) < 0)
			{
				perror("write");
				return -1;
			}
		}

		/*check socket is ready or not ? */
		if(cpoll[1].revents & (POLLIN | POLLERR))
		{
			/*read from socket*/
			if((bytesread = read(sock, buf, sizeof(buf))) < 0)
			{
				perror("read");
				exit(1);
			}else if(bytesread == 0)
			{
				fprintf(stderr, "server disconnect\n");
				exit(0);
			}
			buf[bytesread] = 0;
			printf("%s\n", buf);
		}
	}
	return 0;
}

运行结果是:

root@hdp3:/media/sf_workspace/sangerhoo/unp# ..../................................................................................connection fromm host 127.0.0.1,port 53105, socket 4
.....................
root@hdp3:/media/sf_workspace/sangerhoo/unp# ............/pollserver:4 bytes from 4 :dfd


..../pollserver:4 bytes from 4 :fdf


...../pollserver:10 bytes from 4 :sangerhoo


..../pollserver:6 bytes from 4 :sd


......../pollserver:6 bytes from 4 :hello



-------------------client----------------------

dfd
dfd


fdf
fdf


sangerhoo
sangerhoo


sd^H^H^H
sd


hello
hello




...............................................................................................................................................................................................................................................................................................................................................................................................................................................................


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值