/*
client server model [server]
enviroment : TEST_PORT .. port no. of socket
TEST_HOST .. host name for server
*/
#include "tcp.h"
char *uname,cmd[MAX_LINE],netcmd[MAX_LINE];
int newsockfd;
void prtstat();
char netstr[]="netgrep";
int main(int argc,char *argv[]) {
int sockfd,ret,clilen,childpid;
struct sockaddr_in srv_addr,cli_addr;
char *emsg;
uname = argv[0];
get_env(); /* get host_name/port_no */
sprintf(cmd,"%d", port_no);
strcpy(netcmd,TCP_INSDIR);
strcat(netcmd,netstr);
PRT_TRS("s:socket()\n");
if (( sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
die_err(1);
}
PRT_TRS("e:socket()\n");
/* set addr */
bzero((char *) &srv_addr,SZ_ADDR);
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
srv_addr.sin_port = htons(port_no);
PRT_TRS("s:bind()\n");
ret = bind(sockfd,(struct sockaddr *) &srv_addr,SZ_ADDR);
PRT_TRS("e:bind()\n");
if (ret == -1) die_err(2);
PRT_TRS("s:listen()\n");
listen(sockfd,SZ_QUEUE);
PRT_TRS("e:listen()\n");
clilen = SZ_ADDR;
printf("Server listening to port %d (pid=%d) .....\n",
port_no,getpid());
for (;;) {
PRT_TRS("s:accept()\n");
newsockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&clilen);
PRT_TRS("e:accept()\n");
if (newsockfd < 0) die_err(3);
if ((childpid = fork()) <0) die_err(4);
else if (childpid == 0) { /* child process */
pid_t c_pid = getpid();
prtstat();
printf("++ DServer %d is spawned\n",c_pid);
close(sockfd);
str_echo(newsockfd,c_pid);
close(newsockfd);
printf(" DServer %d is closed socket & exit\n",c_pid);
printf("Server %d listening to port %d ...\n",c_pid,port_no);
fflush(stdout);
printf("-- DServer %d is died\n",c_pid);
exit(0);
}
close(newsockfd); /* parent process */
}
}
void prtstat() {
if (fork() == 0) { /* child process */
printf("\n");
execl(netcmd,netcmd,cmd,(char *) 0);
exit(0);
}
sleep(1);
return;
}
int str_echo(int sockfd,pid_t c_pid) {
int n;
char line[MAX_LINE];
for (;;) {
n = readline(sockfd,line,MAX_LINE);
if (n == 0) return;
else if (n < 0) die_err(8);
if (writen(sockfd,line,n) != n) die_err(9);
printf(" DServer %d : Receive data [%s",c_pid,line);
if (! strcmp(line,DS_CLS_WQUIT)) {
close(sockfd);
printf(" DServer %d : socket closed and wait (%d sec) : DS_CLS_WQUIT \n",
c_pid,WAIT_TIME);
prtstat();
sleep(WAIT_TIME);
return;
}
if (! strcmp(line,DS_QUIT)) return;
if (! strcmp(line,DS_C_QUIT)) return;
if (! strcmp(line,CQUIT_SWQUIT)) {
printf(" DServer %d : socket not closed and wait (%d sec) : CQUIT_SWQUIT\n",
c_pid,WAIT_TIME);
prtstat();
sleep(WAIT_TIME);
return;
}
}
}
int readline(int fd,char *ptr, int maxlen) {
int n,rc;
char c;
for (n=1; n<maxlen; n++) {
if ((rc = read(fd,&c,1)) == 1) {
*ptr++ = c;
if (c == '\n') break;
}
else if (rc == 0) {
if (n == 1) return (0);
else break;
} else return (-1);
}
*ptr = 0;
return (n);
}
int writen(int fd,char *ptr,int nbytes) {
int nleft,nwritten;
nleft = nbytes;
while (nleft > 0) {
nwritten = write(fd,ptr,nleft);
if (nwritten <= 0) return (nwritten);
nleft -= nwritten;
ptr += nwritten;
}
return (nbytes - nleft);
}
void usage() {
}
void die_err(int no) {
perror(uname);
exit(no);
}