Skip to content

Instantly share code, notes, and snippets.

@justdoit0823
Last active May 8, 2017 14:21
Show Gist options
  • Save justdoit0823/93e81ccf7bf3c3e464ccf96d2013b88a to your computer and use it in GitHub Desktop.
Save justdoit0823/93e81ccf7bf3c3e464ccf96d2013b88a to your computer and use it in GitHub Desktop.
#include "stdio.h"
#include "unistd.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MAX_EVENTS 10
int setnonblocking(int fd){
int flag, ret;
flag = fcntl(fd, F_GETFL, NULL);
flag |= O_NONBLOCK;
ret = fcntl(fd, F_SETFL, flag);
return ret;
}
int start_listen_server(const char * host, int port){
int s_sock, flag;
struct sockaddr_in addr;
printf("host %s, port %d\n", host, port);
memset(&addr, 0, sizeof(addr));
inet_aton(host, &addr.sin_addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
s_sock = socket(AF_INET, SOCK_STREAM, 0);
flag = 1;
setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
setnonblocking(s_sock);
bind(s_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr));
listen(s_sock, 5);
return s_sock;
}
const char * get_instance_name(int thread_mode){
return thread_mode ? "thread": "process";
}
void * poll_loop(void * args){
int nfds, conn_sock, listen_sock, addrlen, id, thread_mode;
struct sockaddr_in addr;
struct epoll_event ev, events[MAX_EVENTS];
int epollfd, et_mode;
listen_sock = ((int *)args)[0];
thread_mode = ((int *)args)[1];
et_mode = ((int *)args)[2];
printf("sock %d, thread_mode %d, et mode %d.\n", listen_sock, thread_mode, et_mode);
if(thread_mode == 1) id = pthread_self();
else id = getpid();
printf("run in %s %d.\n", get_instance_name(thread_mode), id);
epollfd = epoll_create1(0);
if (epollfd == -1) {
printf("epoll_create1\n");
exit(1);
}
ev.events = EPOLLIN;
if(et_mode) ev.events |= EPOLLET;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -1) {
printf("epoll_ctl: listen_sock\n");
exit(1);
}
while(1){
printf("epoll wait in %s %u.\n", get_instance_name(thread_mode), id);
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
printf("finish waiting with %d fds in %s %u.\n", nfds, get_instance_name(thread_mode), id);
if (nfds == -1) {
printf("epoll_wait error\n");
break;
}
while(1){
conn_sock = accept(listen_sock, (struct sockaddr *) &addr, &addrlen);
if(conn_sock == -1) {
if(errno == EAGAIN || errno == EWOULDBLOCK){
printf("accept failure in %s %u\n", get_instance_name(thread_mode), id);
break;
}
}
else if(conn_sock > 0){
printf("accept succes %s %u\n", get_instance_name(thread_mode), id);
}
}
}
printf("run in %s %u.\n", get_instance_name(thread_mode), id);
}
int run_thread_server(int argc, char * argv[]){
int server_sock, et_mode;
pthread_t threads[2];
int args[2];
if(argc > 4) et_mode = atoi(argv[4]);
else et_mode = 0;
server_sock = start_listen_server(argv[2], atoi(argv[3]));
args[0] = server_sock;
args[1] = 1;
args[2] = et_mode;
pthread_create(&threads[0], NULL, poll_loop, &args[0]);
pthread_create(&threads[1], NULL, poll_loop, &args[0]);
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
return 0;
}
int run_server(int argc, char * argv[]){
int server_sock, et_mode, pid;
int args[2];
if(argc > 4) et_mode = atoi(argv[4]);
else et_mode = 0;
server_sock = start_listen_server(argv[2], atoi(argv[3]));
pid = fork();
if(pid == -1){
printf("fork error.\n");
exit(0);
}
args[0] = server_sock;
args[1] = 0;
args[2] = et_mode;
if(pid == 0){
poll_loop(&args[0]);
}
else{
poll_loop(&args[0]);
waitpid(pid, NULL, 0);
}
return 0;
}
int main(int argc, char * argv[]){
if(strcmp(argv[1], "thread") == 0) run_thread_server(argc, argv);
else run_server(argc, argv);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment