Date: Mon, 23 Oct 2000 19:10:59 -0500 From: "TAZ Gravel, Emmanuel" <EGravel@taz.telusa.com> To: "'freebsd-net@freebsd.org'" <freebsd-net@freebsd.org> Subject: Socket programming, strange recv reaction Message-ID: <6BFFC6F3FB6AD211A9D800A0C99B3E6F01B3DD70@TEAPHX0031>
next in thread | raw e-mail | index | archive | help
This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C03D4E.E868237A Content-Type: text/plain; charset="iso-8859-1" I'm trying to write a small client-server pair using TCP sockets. I'm not changing the default blocking mechanisms for recv(). The client connects to the server, which sends it a welcome message. Then, the client sends ASCII "commands" that are interpreted by the server (recv'ed, strcmp'ed and answered to). If the command is "unknown" it echoes it back to the client using send(). The client, on the other end, is "waiting" with a recv(). Appart from the first message sent by the client, most others were never echoed back to the client, and when one arrived, it was from a previous message, anywhere between 2 and 8 iterations previous to the one that was just sent. Using ethereal to analyze the traffic, and blocking the server with a 5 second sleep, showed that the recv in the client was accepting a simple ACK message as an acceptable message. The "conversation" is all [PSH, ACK] or [ACK]. Ethereal was set to look at the loopback interface to see this happening, and for some reason all packets were "duplicated" (same time frame, same exact packet, always in pairs). Don't know if this has anything to do with it or not though. I know the problem centers around the recv in the client, however I don't know where to look. Just starting to look at socket programming, and using tutorials and newbie code found online (using Beej's Guide to Network Programming right now). Read the man page for recv() also, and since it's supposed to be blocking until something is recieved, I don't know what to make of this. Inlining my code since I'm using Outlook right now... Thanks for your help! Emmanuel <server code> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <arpa/inet.h> #define MYPORT 4039 /* the port users will be connecting to */ #define MAXBUFLEN 128 #define BACKLOG 10 /* how many pending connections queue will hold */ #define MAXCHILD 5 /* Global variables */ int sockfd; /* listen on sock_fd */ int child[MAXCHILD]; void usage(newfd) int newfd; { char *msg; int numbytes; printf("Sending usage information.\n"); msg = "Usage:\n\thello: returns a message.\n\tquit: exits the session.\n"; if ((numbytes = send(newfd, msg, MAXBUFLEN, 0)) == -1) { perror("send"); exit(1); } printf("Sent [%i] bytes.\nMessage sent is %s\n",numbytes,msg); } void hello(newfd,buf) int newfd; char *buf; { char msg[128] = "You said: "; int numbytes; printf("Entering hello \n"); printf("Replying to [%s].\n",buf); strcat(msg,buf); printf("first strcat\n"); strcat(msg,"\n"); printf("sending message now\n"); sleep(5); if ((numbytes = send(newfd, msg, MAXBUFLEN, 0)) == -1) { perror("send"); close(newfd); exit(1); } printf("Sent [%i] bytes.\nMessage sent is [%s]\n",numbytes,msg); } void bye(newfd) int newfd; { /* signal(SIGINT, finalize); */ /* Only usefull in programs not exiting after signal trap */ char *msg; msg = "Closing connection. Goodbye!\n"; printf("in bye\n"); if (send(newfd, msg, sizeof(msg), 0) == -1) { printf("error in sending\n"); perror("send"); close(newfd); exit(1); } printf("closing now\n"); close(newfd); printf("Closing connection. Child PID is [%i]. \n",getpid()); exit(0); } void finalize() { printf("Closing all connections\n"); while(waitpid(-1,NULL,0) > 0); /* clean up all child processes */ close(sockfd); exit(0); } int main() { int new_fd; /* new connection on new_fd */ int sin_size; struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connector's address information */ int numberbytes; /* int i, addre_len; */ char buf[MAXBUFLEN]; unsigned short int children; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } signal(SIGINT, finalize); my_addr.sin_family = AF_INET; /* host byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* automatically fill with my IP */ bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */ if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } children = 0; while(1) { /* main accept() loop */ sin_size = sizeof(struct sockaddr_in); if (children < MAXCHILD) { if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { perror("accept"); continue; } printf("server: got connection from [%s]\n", inet_ntoa(their_addr.sin_addr)); if (!fork()) { /* this is the child process */ /* Anything that happens here is only executed by the child, * and that's the only thing that the child executes. */ if (send(new_fd, "Welcome to my world!\nWhat is your pleasure?\n", 44, 0) == -1) { perror("send"); close(new_fd); exit(1); } while(1) { if ((numberbytes = recv(new_fd,buf,MAXBUFLEN,0)) == -1) { perror("recv"); continue; } buf[numberbytes] = '\0'; printf("numberbytes = [%i]\nbuffer = [%s]\n",numberbytes,buf); if(!strcmp(buf, "")) { printf("printing usage\n"); usage(new_fd); } else if(!strncmp(buf, "quit", 4)) { printf("calling bye\n"); bye(new_fd); } else { printf("calling hello\n"); hello(new_fd,buf); } } } } /* clean up all child processes */ while(waitpid(-1,NULL,WNOHANG) > 0); } } <client code> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <arpa/inet.h> #define PORT 4039 /* the port client will be connecting to */ #define MAXDATASIZE 100 /* max number of bytes we can get at once */ int main(int argc, char *argv[]) { int sockfd, numbytes; char buf[MAXDATASIZE],msg[MAXDATASIZE] = "sta"; struct hostent *he; struct sockaddr_in their_addr; /* connector's address information */ /* printf("Before init\n"); */ if (argc != 2) { fprintf(stderr,"usage: manuclient hostname\n"); /* put actual error message here */ exit(1); } /*printf("Before gethostbyname\n"); */ if ((he=gethostbyname(argv[1])) == NULL) { /* get the host info */ perror("gethostbyname"); exit(1); } /*printf("Host is %s\nBeofre socket creation\n", *((struct in_addr *)he->h_addr)); */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } /* printf("Socket created. Before socket connection.\n"); */ their_addr.sin_family = AF_INET; /* host byte order */ their_addr.sin_port = htons(PORT); /* short, network byte order */ their_addr.sin_addr = *((struct in_addr *)he->h_addr); bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */ if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } /*printf("Socket connected. Before while loop, value is %i\n",strcmp(msg,"quit")); */ while(strcmp(msg,"quit")) { /* Begin chat routine with the server */ printf("Before recv\n"); /*sleep(5);*/ if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) { perror("recv"); exit(1); } printf("After recv\n"); buf[numbytes] = '\0'; printf("Received: %s\n",buf); printf("Command > "); scanf("%s",msg); /* if (sizeof(msg) >= MAXDATASIZE) msg[MAXDATASIZE] = '\0'; */ printf("Size of message is %i\n",sizeof(msg)); if ((numbytes = send(sockfd, msg, MAXDATASIZE, 0)) == -1) { perror("send"); exit(1); } printf("sent message %s to %s\nNumber of bytes sent is %i\n",msg,inet_ntoa(their_addr.sin_addr),numbytes); if(!strcmp(msg,"quit")) printf("Recieved quit command, exiting!\n"); } close(sockfd); return 0; } ------_=_NextPart_001_01C03D4E.E868237A Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = charset=3Dus-ascii"> <META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version = 5.5.2650.12"> <TITLE>Socket programming, strange recv reaction</TITLE> </HEAD> <BODY> <P><FONT SIZE=3D2 FACE=3D"Arial">I'm trying to write a small = client-server pair using TCP sockets.</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">I'm not changing the default blocking = mechanisms for recv().</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">The client connects to the server, = which sends it a welcome</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">message. Then, the client sends ASCII = "commands" that are</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">interpreted by the server (recv'ed, = strcmp'ed and answered to).</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">If the command is "unknown" = it echoes it back to the client</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">using send(). The client, on the = other end, is "waiting" with a</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">recv().</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">Appart from the first message sent by = the client, most others</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">were never echoed back to the client, = and when one arrived, it</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">was from a previous message, anywhere = between 2 and 8 iterations</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">previous to the one that was just = sent. Using ethereal to analyze</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">the traffic, and blocking the server = with a 5 second sleep, showed</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">that the recv in the client was = accepting a simple ACK message</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">as an acceptable message. The = "conversation" is all [PSH, ACK]</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">or [ACK]. Ethereal was set to look at = the loopback interface to</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">see this happening, and for some = reason all packets were</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">"duplicated" (same time = frame, same exact packet, always in</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">pairs). Don't know if this has = anything to do with it or not</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">though.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">I know the problem centers around the = recv in the client, however</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">I don't know where to look. Just = starting to look at socket</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">programming, and using tutorials and = newbie code found online</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">(using Beej's Guide to Network = Programming right now).</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">Read the man page for recv() also, and = since it's supposed to</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">be blocking until something is = recieved, I don't know what to</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">make of this.</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">Inlining my code since I'm using = Outlook right now...</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">Thanks for your help!</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">Emmanuel</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"><server code></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <stdio.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <stdlib.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <errno.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <signal.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <string.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <unistd.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/types.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <netinet/in.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/socket.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/wait.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <arpa/inet.h></FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">#define MYPORT 4039 = /* the port users will be connecting to */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">#define MAXBUFLEN 128</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">#define BACKLOG = 10 /* how many pending connections queue will = hold */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#define MAXCHILD 5</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">/* Global variables */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">int sockfd; /* listen on sock_fd = */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">int child[MAXCHILD];</FONT> </P> <BR> <P><FONT SIZE=3D2 FACE=3D"Arial">void usage(newfd)</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int = newfd;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char *msg;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int numbytes;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Sending usage = information.\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> msg =3D "Usage:\n\thello: = returns a message.\n\tquit: exits the session.\n";</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if ((numbytes =3D send(newfd, = msg, MAXBUFLEN, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("send");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = exit(1); </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Sent [%i] = bytes.\nMessage sent is %s\n",numbytes,msg);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">void hello(newfd,buf)</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int = newfd;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char = *buf;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char msg[128] =3D "You = said: ";</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int numbytes;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Entering hello = \n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Replying to = [%s].\n",buf);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> strcat(msg,buf);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("first = strcat\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = strcat(msg,"\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("sending message = now\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> sleep(5);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if ((numbytes =3D send(newfd, = msg, MAXBUFLEN, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("send");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = close(newfd);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Sent [%i] = bytes.\nMessage sent is [%s]\n",numbytes,msg);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">void bye(newfd)</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int = newfd;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /* signal(SIGINT, finalize); = */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /* Only usefull in programs = not exiting after signal trap */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char *msg;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> msg =3D "Closing = connection. Goodbye!\n";</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("in = bye\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if (send(newfd, msg, = sizeof(msg), 0) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("error = in sending\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("send");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = close(newfd);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("closing = now\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> close(newfd);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Closing = connection. Child PID is [%i]. \n",getpid());</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(0);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">void finalize()</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{ </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Closing all = connections\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> while(waitpid(-1,NULL,0) > = 0); /* clean up all child processes */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> close(sockfd);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(0);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> <BR> <P><FONT SIZE=3D2 FACE=3D"Arial">int main()</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int new_fd; = /* new connection on new_fd */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int = sin_size;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> struct sockaddr_in = my_addr; /* my address information */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> struct sockaddr_in = their_addr; /* connector's address information */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int = numberbytes;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = /* int i, addre_len; */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char = buf[MAXBUFLEN];</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> unsigned short int = children;</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if ((sockfd =3D = socket(AF_INET, SOCK_STREAM, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = perror("socket");</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> signal(SIGINT, = finalize);</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> my_addr.sin_family = =3D AF_INET; /* host = byte order */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> my_addr.sin_port = =3D htons(MYPORT); /* short, network byte order = */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = my_addr.sin_addr.s_addr =3D INADDR_ANY; /* automatically fill with my = IP */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = bzero(&(my_addr.sin_zero), = 8); /* zero the rest of the = struct */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if (bind(sockfd, = (struct sockaddr *)&my_addr,</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; sizeof(struct sockaddr)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = perror("bind");</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if (listen(sockfd, = BACKLOG) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = perror("listen");</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> children =3D = 0;</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> while(1) { /* = main accept() loop */</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> sin_size =3D = sizeof(struct sockaddr_in);</FONT> <BR> =20 <BR> <FONT SIZE=3D2 = FACE=3D"Arial">if (children < MAXCHILD) {</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> if ((new_fd =3D accept(sockfd,</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; &nb= sp; (struct sockaddr = *)&their_addr,</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; &nb= sp; &sin_size)) = =3D=3D -1) {</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> perror("accept");</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> continue;</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> printf("server: got connection from = [%s]\n",</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; = inet_ntoa(their_addr.sin_addr));</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> if (!fork()) { /* this is the child process = */</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> /* Anything that happens here is only = executed by the child,</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> * and that's the only thing = that the child executes. */</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; if (send(new_fd,</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; = "Welcome to my world!\nWhat is your pleasure?\n",</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> &nb= sp; 44, 0) = =3D=3D -1) {</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> = perror("send");</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> close(new_fd);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> exit(1);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> </FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> while(1) {</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> </FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> if ((numberbytes =3D = recv(new_fd,buf,MAXBUFLEN,0)) =3D=3D -1) {</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">perror("recv");</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">continue;</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> </FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> buf[numberbytes] =3D = '\0';</FONT> </P> <P> <FONT SIZE=3D2 = FACE=3D"Arial"> printf("numberbytes = =3D [%i]\nbuffer =3D [%s]\n",numberbytes,buf);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> </FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> if(!strcmp(buf, = "")) {</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">printf("printing usage\n");</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">usage(new_fd);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> else if(!strncmp(buf, = "quit", 4)) {</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">printf("calling bye\n");</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">bye(new_fd);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> else {</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">printf("calling hello\n");</FONT> <BR> = <FONT SIZE=3D2 = FACE=3D"Arial">hello(new_fd,buf);</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial"> }</FONT> <BR> <FONT SIZE=3D2 = FACE=3D"Arial">}</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> /* clean up = all child processes */</FONT> <BR><FONT SIZE=3D2 = FACE=3D"Arial"> = while(waitpid(-1,NULL,WNOHANG) > 0);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"><client code></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <stdio.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <stdlib.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <errno.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <string.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <netdb.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <unistd.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/types.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <netinet/in.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/socket.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <sys/wait.h></FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">#include <arpa/inet.h></FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">#define PORT 4039 /* = the port client will be connecting to */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">#define MAXDATASIZE 100 /* max number = of bytes we can get at once */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial">int main(int argc, char = *argv[])</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">{</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> int sockfd, numbytes; = </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> char = buf[MAXDATASIZE],msg[MAXDATASIZE] =3D "sta";</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> struct hostent *he;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> struct sockaddr_in their_addr; = /* connector's address information */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> /* printf("Before = init\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if (argc !=3D 2) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = fprintf(stderr,"usage: manuclient hostname\n"); /* put actual = error message here */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /*printf("Before = gethostbyname\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if = ((he=3Dgethostbyname(argv[1])) =3D=3D NULL) { /* get the host = info */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("gethostbyname");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /*printf("Host is = %s\nBeofre socket creation\n", *((struct in_addr = *)he->h_addr));</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> if ((sockfd =3D = socket(AF_INET, SOCK_STREAM, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("socket");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /* printf("Socket = created. Before socket connection.\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> their_addr.sin_family =3D = AF_INET; /* host byte = order */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> their_addr.sin_port =3D = htons(PORT); /* short, network byte order = */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> their_addr.sin_addr =3D = *((struct in_addr *)he->h_addr);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = bzero(&(their_addr.sin_zero), = 8); /* zero the rest of the = struct */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if (connect(sockfd, (struct = sockaddr *)&their_addr, sizeof(struct sockaddr)) =3D=3D -1) = {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("connect");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> /*printf("Socket = connected. Before while loop, value is = %i\n",strcmp(msg,"quit"));</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = while(strcmp(msg,"quit")) { /* Begin chat routine = with the server */</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> printf("Before = recv\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = /*sleep(5);*/</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if = ((numbytes=3Drecv(sockfd, buf, MAXDATASIZE, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("recv");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> printf("After = recv\n");</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> buf[numbytes] =3D = '\0';</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = printf("Received: %s\n",buf);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = printf("Command > ");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = scanf("%s",msg);</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> /* if = (sizeof(msg) >=3D MAXDATASIZE)</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = msg[MAXDATASIZE] =3D '\0';</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> */</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("Size = of message is %i\n",sizeof(msg));</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> if ((numbytes =3D = send(sockfd, msg, MAXDATASIZE, 0)) =3D=3D -1) {</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = perror("send");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = exit(1);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> printf("sent = message %s to %s\nNumber of bytes sent is = %i\n",msg,inet_ntoa(their_addr.sin_addr),numbytes);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = if(!strcmp(msg,"quit"))</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> = printf("Recieved quit command, exiting!\n");</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> }</FONT> </P> <P><FONT SIZE=3D2 FACE=3D"Arial"> close(sockfd);</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> </FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial"> return 0;</FONT> <BR><FONT SIZE=3D2 FACE=3D"Arial">}</FONT> </P> </BODY> </HTML> ------_=_NextPart_001_01C03D4E.E868237A-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6BFFC6F3FB6AD211A9D800A0C99B3E6F01B3DD70>