網絡編程 poll

寫下來,怕忘記了

// server

#include <iostream>
#include <vector>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <poll.h>
#include <sys/time.h>  // gettimeofday()
#include <netinet/in.h>  // struct in_addr
#include <arpa/inet.h> // inet_aton()
#include <unistd.h>  // getpid()
#include <fcntl.h>
#include <cerrno>
//#define NDEBUG
#include <cassert>
using namespace std;
#define MAX_CONNECT 5
void nothing(int i)
{
	cerr << "signal: " << i << endl;
}
int main()
{
	int nacc = 0;
	bool maxconn = false;  

	int n;
	cout << getpid() << endl;
	//signal(SIGINT,nothing); // Ctrl+c
	signal(SIGUSR1,nothing); // kill -10 pid. Test EINTR
	char buf[BUFSIZ];
	struct sockaddr_in addr= {0};
	struct sockaddr_in cli_addr= {0};
	socklen_t cli_len = sizeof cli_addr;

	short port;
	int fd = socket(PF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket()");
		return 1;
	}


	int flags = fcntl(fd,F_GETFL,0);
	flags |= O_NONBLOCK;
	//fcntl(fd,F_SETFL,flags);

	addr.sin_family = AF_INET;
	//n = inet_aton("127.0.0.1",&addr.sin_addr);
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(6219);

	n = bind(fd,(struct sockaddr*) &addr,sizeof(addr));
	if(n < 0)
	{
		perror("bind()");
		return 2;
	}

	n = listen(fd,2);
	if(n < 0)
	{
		perror("listen()");
		return 3;
	}

	vector<int> fdvec;
	fdvec.push_back(fd);

	while(1)
	{
		struct pollfd fds[MAX_CONNECT + 1];
		memset(fds,0,sizeof(fds));
		int index = 0;

		vector<int>::const_iterator it;
		for(it=fdvec.begin();it!=fdvec.end();++it)
		{
			fds[index].fd = *it;
			fds[index].events |= POLLIN;
			index++;
		}

		cerr << "poll...index:" << index;
		n = poll(fds,index,5000 /*milliseconds -1 */ );
		cerr << " Done. " << n << endl;
		if(n < 0)
		{
			perror("poll()");
			if(EINTR == errno) continue;

			return 4;
		}
		else if (0 == n)
		{
			cout << "Timeout." << endl;
			continue;
		}
		else
		{
			int readyfds = n;
			for(int i=0; i<index; i++)
			{
				if(!readyfds) break;

				if(!(fds[i].revents & POLLIN))
					continue;
				cerr << "for."<< i << endl;
				if(fds[i].fd == fd)
				{ // accept
					int newfd = accept(fd,(struct sockaddr*)&cli_addr,&cli_len);
					cerr << "accept:" << newfd << endl;
					if(newfd < 0)
					{
						perror("accept()");
						return 5;
					}
					fdvec.push_back(newfd);
					--readyfds;
					if(fdvec.size()+1 > MAX_CONNECT)
					{
						fdvec.erase(find(fdvec.begin(),fdvec.end(),fd));
						maxconn = true;
					}
				}
				else
				{ // read
					cerr << "read:" << fds[i].fd << endl;
					char buf[BUFSIZ] = {0};
					int n = read(fds[i].fd,buf,sizeof(buf));
					--readyfds;
					if(n < 0)
					{
						perror("read()");
						if(EINTR == errno)
						{
							continue;
						}
						return 6;
					}
					if(0 == n)
					{ // client closed or network down.
						close(fds[i].fd);
						fdvec.erase(find(fdvec.begin(),fdvec.end(),fds[i].fd));
						if(maxconn)
						{
							maxconn = false;
							fdvec.push_back(fd);
						}
						continue;
					}
					int m = write(fds[i].fd,buf,n);
					if(m < 0)
					{
						perror("write()");
						return 7;
					}
				}
			}
			if(readyfds)
				cerr << "some fd don't proccess." << endl;

		}
	}

	return 0;
}

// client

參見:http://blog.csdn.net/fym0121/article/details/8056776


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章