poll之客户端与服务端聊天

24 篇文章 0 订阅
7 篇文章 0 订阅
<pre name="code" class="cpp">// client.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <poll.h>

#define MAXLEN 100


int main()
{
	int sock, nread, nready;
	if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
		perror("socket error!");

	struct sockaddr_in servaddr;
	memset(&servaddr, 0, sizeof(servaddr));

	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(6000);
	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	char buf[MAXLEN];
	struct pollfd fdarr[2];

	if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
	{
		perror("connect error.");
		exit(1);
	}	

	fdarr[0].fd = fileno(stdin);
	fdarr[0].events = POLLRDNORM;
	fdarr[1].fd = sock;
	fdarr[1].events = POLLRDNORM;

	while(1)
	{
		nready = poll(fdarr, 2, -1); // -1 let poll wait forever
		
		if(fdarr[0].revents & POLLRDNORM)
		{
			if((fgets(buf, MAXLEN, stdin)) != NULL)
				write(fdarr[1].fd, buf, strlen(buf));
			memset(buf, 0, sizeof(buf));
		}
		if(fdarr[1].revents & POLLRDNORM)
		{
			if((nread = read(fdarr[1].fd, buf, MAXLEN)) < 0)
			{
				if(errno == ECONNRESET)
				{
					close(fdarr[1].fd);
				}
			}
			else if(nread == 0)
				close(fdarr[1].fd);
			else
			{
				fputs(buf,stdout);
				memset(buf, 0, sizeof(buf));
			}
		}
	}

	return 0;
}

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

#define MAXLEN 100



int main()
{
	int i, listenfd, nready, clilen;
	struct pollfd client[3];
	char buf[MAXLEN];
	if((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
		perror("socket error!");

	struct sockaddr_in servaddr;
	struct sockaddr_in cliaddr;
	
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(6000);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

	if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
		perror("bind error!");
	if(listen(listenfd, SOMAXCONN) < 0)
		perror("listen");
	
	int conn, maxi, nread;
	
	client[0].fd = listenfd;
	client[0].events = POLLRDNORM;
	int stdinfd = fileno(stdin);

	client[1].fd = stdinfd;
        client[1].events = POLLRDNORM;
	client[2].fd = -1;
        client[2].events = POLLRDNORM;
	
	maxi = 2;
	while(1)
	{
		nready = poll(client, maxi, -1); // -1 let poll wait forever
		if(client[0].revents & POLLRDNORM)
		{
			fprintf(stdout, "%s\n","New connection.");
			clilen = sizeof(cliaddr);
			conn = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);
			client[2].fd = conn;
			maxi = 3;	
		}
		
		if(client[1].revents & POLLRDNORM)
		{
			if((fgets(buf, MAXLEN, stdin)) != NULL)
				write(client[2].fd, buf, strlen(buf));
			memset(buf, 0, sizeof(buf));
		}
		if(client[2].revents & POLLRDNORM)
		{
			if((nread = read(client[2].fd, buf, MAXLEN)) < 0)
			{
				if(errno == ECONNRESET)
				{
					close(client[2].fd);
				}
			}
			else if(nread == 0)
				close(client[2].fd);
			else
			{
				fputs(buf,stdout);
				memset(buf, 0, sizeof(buf));
			}
		}
	}
	close(listenfd);
	return 0;
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值