linux network server (pthread)

#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);
}

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));
					}
				}
			}
		}
	}
}