网络编程 select

写下来,看给忘了

man 7 ip

man 7 tcp

// server
#include <iostream>
#include <vector>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/select.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 3
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;
	}

	for(int i=0; i<3; i++)
	{
		struct timeval tv = {0,1000 * 100};
		struct timeval now;
		select(0,NULL,NULL,NULL,&tv); // delay.
		gettimeofday(&now,NULL);
		cerr << "Time: " << now.tv_sec <<"."<<now.tv_usec << endl;
	}

	fd_set orset;
	FD_ZERO(&orset);
	FD_SET(fd,&orset);
	FD_SET(fd,&orset);
	FD_SET(fd,&orset);
	FD_SET(fd,&orset);
	int nfds = fd;
	vector<int> fdvec;
	fdvec.push_back(fd);
	while(1)
	{
		fd_set rset;
		fd_set wset;
		fd_set eset;
		FD_ZERO(&rset);
		FD_ZERO(&wset);
		FD_ZERO(&eset);
		rset = orset;
		//wset = orset;
		eset = orset;
		cerr << "select ... ";
		struct timeval tv={3,0};
		n = select(nfds+1,&rset,&wset,&eset,&tv);
		cerr << "Done. " << n << endl;
		if(n < 0)
		{
			perror("select()");
			if(EINTR == errno){
				cerr << "get EINTR. We cotinue."<< endl;
			   	continue;
			}

			return 4;
		}
		else if(n)
		{
			int readyfds = n;
			if(FD_ISSET(fd,&rset))
			{
				if(nacc > MAX_CONNECT) //limit the max connection.
				{
					FD_CLR(fd,&orset);
					maxconn  = true;
					continue;
				}
				int newfd = accept(fd,(struct sockaddr*)&cli_addr,&cli_len);
				if(newfd < 0)
				{
					perror("accept()");
					return 5;
				}
				if(newfd > nfds) nfds = newfd;
				fdvec.push_back(newfd);
				FD_SET(newfd,&orset);
				int flags = fcntl(newfd,F_GETFL);
				flags |= O_NONBLOCK;
				fcntl(newfd,F_SETFL,flags);
				cout << "accept: " << ++nacc << endl;

				if(--readyfds == 0) continue;
			}
			
			vector<int>::const_iterator it;
			vector<int> tmpvec(fdvec);
			for(it=tmpvec.begin(); it != tmpvec.end(); it++)
			{
				if(*it == fd) continue;

				if(FD_ISSET(*it,&rset))
				{
					cerr<< "read fds"<<endl;
					char buf[BUFSIZ] = {0};
					n = read(*it,buf,sizeof(buf));
					if(n < 0)
					{
						if(EINTR == errno) continue;

						perror("read()");
						return 6;
					}
					else if(0 == n)   // client close socket.
					{ // client down network.
						close(*it);
						FD_CLR(*it,&orset);
						fdvec.erase(find(fdvec.begin(),fdvec.end(),*it));
						cout << "accept: " << --nacc << endl;
						if(nacc <= MAX_CONNECT)
						{
							FD_SET(fd,&orset);
						}

						if(0 == --readyfds) break;
						continue;
					}
					write(*it,buf,n);
					if(0 == --readyfds) break;
				}
				if(FD_ISSET(*it,&wset))
				{
					cerr << "write fds" << endl;
				}

				
				if(FD_ISSET(*it,&eset))
				{
					cerr << "exception fd" << endl;
				}
			}
			if(readyfds != 0)
				cerr << "Are there any fd left?" << endl;
		}
		else
		{
			cout << "Timeout." << endl;
		}
	}

	return 0;
}

// client
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;
int main()
{
	char buf[BUFSIZ] = {0};
	struct sockaddr_in addr = {0};
	int fd = socket(PF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket()");
		return 1;
	}

	addr.sin_family = AF_INET;
	inet_aton("127.0.0.1",&addr.sin_addr);
	addr.sin_port = htons(6219);
	int n = connect(fd,(struct sockaddr*)&addr,sizeof addr);
	if(n < 0)
	{
		perror("connect()");
		return 1;
	}

	write(fd,"hello",5);
	read(fd,buf,sizeof buf);
	cerr << buf ;
	sleep(100);

	close(fd);
	return 0;
}


你可能感兴趣的:(编程,网络,struct,socket,Stream,null)