#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#define PORT 1656
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
void do_echo(int);
void sigHandler(int);
readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return (-1);
} else if (nread == 0)
break; /* EOF */
nleft -= nread;
ptr += nread;
}
return (n-nleft);
}
writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
char *ptr;
ptr = vptr;
nleft = n;
while (nleft > 0) {
if ((nwritten = write (fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
nwritten = 0; /* and call write() again */
else
return (-1);
}
nleft -= nwritten;
ptr += nwritten;
}
return (n); /* return >= 0 */
}
int main()
{
int c_socket, s_socket;
struct sockaddr_in s_addr, c_addr;
char buffer[BUFSIZ];
int len=0;
pid_t pid;
int state;
struct sigaction act;
int recv_len=0;
int send_len=0;
int send_len2=0;
act.sa_handler = sigHandler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
state = sigaction(SIGCHLD, &act, 0);
if(state != 0){
printf("signal error\n");
exit(1);
}
s_socket = socket(PF_INET, SOCK_STREAM, 0);
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
if(bind(s_socket, (struct sockaddr *)&s_addr, sizeof(s_addr)) == -1)
{
printf("Can not bind\n");
return -1;
}
if(listen(s_socket, 5) == -1)
{
printf("listen fail\n");
return -1;
}
while(1){
len = sizeof(c_addr);
if((c_socket=accept(s_socket, (struct sockaddr *)&c_addr,&len))<0){
printf("accept error\n");
}
if((pid=fork())<0){
printf("echo server can't fork()\n");
exit(1);
}
else if(pid>0){
close(c_socket);
continue;
}
else if(pid == 0){
printf("Child create");
close(s_socket);
printf("CLIENT IP : %s",inet_ntoa(c_addr.sin_addr));
do_echo(c_socket);
}
}
close(c_socket);
exit(1);
}
void do_echo(int cSock){
char buffer[BUFSIZ];
int recv_len;
int send_len;
int send_len2;
while(1)
{
memset(buffer,0,BUFSIZ);
readn(cSock, &recv_len, sizeof(int));
printf("\nReceived Size(hton) : %d\n", recv_len);// 받은 데이터 출력
recv_len = ntohl(recv_len); // 받은 데이터 사이즈를 host로 변환
printf("Received Size(ntoh) : %d", recv_len); // 받은 데이터 출력
readn(cSock,buffer,recv_len);
printf("\nPID : %d", getpid()); // PID 출력
printf("\nreceived message : %s",buffer); // 메시지출력
if(strcmp("q",buffer) == 0){
break;
}
send_len = recv_len/2; // 임의의 길이 설정
send_len2 = htonl(send_len);
writen(cSock,&send_len2,sizeof(int)); // 버퍼에 메시지 기록
writen(cSock,buffer,send_len);
}
close(cSock);
//exit(1);
}
void sigHandler(int sig){// signal 핸들러
int pid;
int status;
pid = wait(&status); // 좀비프로세스 생성 방지
printf("pid[%d] terminate\n", pid);
exit(1);
}