寫下來,怕忘記了
// 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