#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/stat.h> #include <arpa/inet.h> #include <pthread.h> void *do_thread(void *arg); struct tharg { struct sockaddr_in client_addr; int csock; }; int main() { int ssock,csock; int clen; struct sockaddr_in client_addr,server_addr; pthread_t tid; if((ssock=socket(AF_INET,SOCK_STREAM,0))<0) { perror("socket error:"); exit(1); } clen=sizeof(client_addr); memset(&server_addr,0x00,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(1337); if(bind(ssock,(struct sockaddr *) &server_addr,sizeof(server_addr))<0) { perror("bind error:"); exit(1); } if(listen(ssock,5)<0) { perror("listen error:"); exit(1); } while(1) { csock=accept(ssock,(struct sockaddr *) &client_addr,&clen); struct tharg arg; arg.client_addr=client_addr; arg.csock=csock; if(pthread_create(&tid,NULL,do_thread,(void *)&arg)<0) { perror("thread create error:"); exit(1); } } return 0; } void *do_thread(void *arg) { int csock; pthread_t tid; char buf[256]={0,}; tid=pthread_self(); char addr[16]; struct tharg args=*(struct tharg *)arg; csock=args.csock; sprintf(addr,"%s",inet_ntoa(args.client_addr.sin_addr)); printf("new thread %x is created from (%s)\n",(unsigned int) tid,addr); while(read(csock,buf,255)>0) { if(strcmp(buf,"exit\x0d\x0a")==0) { write(csock,"bye!!\n",6); break; } if(write(csock,buf,strlen(buf))<=0) { perror("write error:"); close(csock); pthread_exit(NULL); } memset(buf,0x00,sizeof(buf)); } close(csock); printf("%x thread is end from (%s)\n",(unsigned int) tid,addr); pthread_exit(NULL); }
Tag: Server
linux network server (epoll)
다중접속이 처리되기는 하지만 write(); 앞에 sleep(10); 등을 넣어서 컴파일 후 클라이언트 두개를 동시에 사용하면 한개씩 처리하는것을 알 수 있다.
다중스레드를 사용하지 않는 한 간단한 일밖에 하지 못한다.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/epoll.h> #include <arpa/inet.h> #include <sys/socket.h> #include <netinet/in.h> #include <fcntl.h> #include <sys/ioctl.h> #define SA struct sockaddr #define EPOLL_SIZE 20 int main(int argc,char *argv[]) { struct sockaddr_in addr,clientaddr; struct eph_comm *conn; int sfd; int cfd; int clilen; int flags=1; int n,i; int readn; struct epoll_event *events; int efd; char buf_in[256]; events=(struct epoll_event *) malloc(sizeof(*events)*EPOLL_SIZE); if((efd=epoll_create(EPOLL_SIZE))<0) { perror("epoll_create error:"); return 1; } clilen=sizeof(clientaddr); sfd=socket(AF_INET,SOCK_STREAM,0); if(sfd==-1) { perror("socket error:"); close(sfd); return 1; } addr.sin_family=AF_INET; addr.sin_port=htons(4445); addr.sin_addr.s_addr=htons(INADDR_ANY); if(bind(sfd,(struct sockaddr *) &addr,sizeof(addr))==-1) { close(sfd); return 1; } listen(sfd,5); events->events=EPOLLIN; events->data.fd=sfd; epoll_ctl(efd,EPOLL_CTL_ADD,sfd,events); while(1) { n=epoll_wait(efd,events,EPOLL_SIZE,-1); if(n==-1) { perror("epoll wait error:"); } for(i=0;i<n;i++) { if(events[i].data.fd==sfd) { //printf("Accept:"); cfd=accept(sfd,(SA *) &clientaddr,&clilen); printf("Accept: %d\n",cfd); events->events=EPOLLIN; events->data.fd=cfd; epoll_ctl(efd,EPOLL_CTL_ADD,cfd,events); } else { memset(buf_in,0x00,256); readn=read(events[i].data.fd,buf_in,255); if(readn<=0) { epoll_ctl(efd,EPOLL_CTL_DEL,events[i].data.fd,events); close(events[i].data.fd); printf("Close: %d\n",events[i].data.fd); } else { printf("read data: %s",buf_in); /* int count; for(count=0;count<readn;count++) { printf("0x%02x ",buf_in[count]); } */ if(strcmp(buf_in,"exit\x0d\x0a")==0) { write(events[i].data.fd,"bye!!\n",6); epoll_ctl(efd,EPOLL_CTL_DEL,events[i].data.fd,events); close(events[i].data.fd); printf("Exit: %d\n",events[i].data.fd); } else { write(events[i].data.fd,buf_in,strlen(buf_in)); } } } } } }