#define IP "127.0.0.1" #define PORT 8888 #define WORKER 4
intworker(int listenfd, int i) { while (1) { printf("I am worker %d, begin to accept connection.\n", i); structsockaddr_inclient_addr; socklen_t client_addrlen = sizeof( client_addr ); int connfd = accept( listenfd, ( struct sockaddr* )&client_addr, &client_addrlen ); if (connfd != -1) { printf("worker %d accept a connection success.\t", i); printf("ip :%s\t",inet_ntoa(client_addr.sin_addr)); printf("port: %d \n",client_addr.sin_port); } else { printf("worker %d accept a connection failed,error:%s", i, strerror(errno)); close(connfd); } } return0; }
intmain() { int i = 0; structsockaddr_inaddress; bzero(&address, sizeof(address)); address.sin_family = AF_INET; inet_pton( AF_INET, IP, &address.sin_addr); address.sin_port = htons(PORT); int listenfd = socket(PF_INET, SOCK_STREAM, 0); assert(listenfd >= 0);
int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address)); assert(ret != -1);
ret = listen(listenfd, 5); assert(ret != -1);
for (i = 0; i < WORKER; i++) { printf("Create worker %d\n", i+1); pid_t pid = fork(); /*child process */ if (pid == 0) { worker(listenfd, i); }
if (pid < 0) { printf("fork error"); } }
/*wait child process*/ int status; wait(&status); return0; }
编译执行,在本机上使用telnet 127.0.0.1 8888测试,结果如下所示
1 2 3 4 5 6 7 8 9 10 11 12
|># ./a.out Create worker 1 Create worker 2 I am worker 0, begin to accept connection. Create worker 3 I am worker 1, begin to accept connection. Create worker 4 I am worker 2, begin to accept connection. I am worker 3, begin to accept connection. worker 0 accept a connection success. ip :127.0.0.1 port: 33141 I am worker 0, begin to accept connection.
staticintmake_socket_non_blocking(int sfd) { int flags, s; flags = fcntl (sfd, F_GETFL, 0); if (flags == -1) { perror ("fcntl"); return-1; } flags |= O_NONBLOCK; s = fcntl (sfd, F_SETFL, flags); if (s == -1) { perror ("fcntl"); return-1; } return0; }
voidworker(int sfd, int efd, struct epoll_event *events, int k) { /* The event loop */ while (1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); printf("worker %d return from epoll_wait!\n", k); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events &EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } elseif (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { printf("worker %d accept failed!\n", k); break; } printf("worker %d accept successed!\n", k); /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ close(infd); } } } }
intmain(int argc, char *argv[]) { int sfd, s; int efd; structepoll_eventevent; structepoll_event *events; sfd = create_and_bind(); if (sfd == -1) { abort (); } s = make_socket_non_blocking (sfd); if (s == -1) { abort (); } s = listen(sfd, SOMAXCONN); if (s == -1) { perror ("listen"); abort (); } efd = epoll_create(MAXEVENTS); if (efd == -1) { perror("epoll_create"); abort(); } event.data.fd = sfd; event.events = EPOLLIN; s = epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event); if (s == -1) { perror("epoll_ctl"); abort(); }
/* Buffer where events are returned */ events = calloc(MAXEVENTS, sizeof event); int k; for(k = 0; k < PROCESS_NUM; k++) { printf("Create worker %d\n", k+1); int pid = fork(); if(pid == 0) { worker(sfd, efd, events, k); } } int status; wait(&status); free (events); close (sfd); return EXIT_SUCCESS; }
voidworker(int sfd, int efd, struct epoll_event *events, int k) { /* The event loop */ while (1) { int n, i; n = epoll_wait(efd, events, MAXEVENTS, -1); /*keep running*/ sleep(4); printf("worker %d return from epoll_wait!\n", k); for (i = 0; i < n; i++) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events &EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf (stderr, "epoll error\n"); close (events[i].data.fd); continue; } elseif (sfd == events[i].data.fd) { /* We have a notification on the listening socket, which means one or more incoming connections. */ struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof in_addr; infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { printf("worker %d accept failed,error:%s\n", k, strerror(errno)); break; } printf("worker %d accept successed!\n", k); /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ close(infd); } } } }