写下来,看给忘了
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; }