From owner-freebsd-net Mon Oct 23 17:11:40 2000 Delivered-To: freebsd-net@freebsd.org Received: from teaausdmz001.telusa.com (teaausdmz001.telusa.com [208.218.238.10]) by hub.freebsd.org (Postfix) with ESMTP id 6147337B4C5 for ; Mon, 23 Oct 2000 17:11:16 -0700 (PDT) Received: from [172.17.250.2] by teaausdmz001.telusa.com (Post.Office MTA v3.5.1 release 219 ID# 0-0U10L2S100) with SMTP id com for ; Mon, 23 Oct 2000 19:01:58 -0500 Received: from teaaushub001.telusa.com ( [172.17.40.252]) by with SMTP (MailShield v1.5); Mon, 23 Oct 2000 19:01:57 -0500 Received: from teaaus0030.telusa.com ([172.17.40.130]) by teaaushub001.telusa.com (Post.Office MTA v3.5.1 release 219 ID# 0-57493U100L2S100V35) with ESMTP id com for ; Mon, 23 Oct 2000 19:11:28 -0500 Received: by teaaus0030.telusa.com with Internet Mail Service (5.5.2650.21) id ; Mon, 23 Oct 2000 19:11:10 -0500 Message-ID: <6BFFC6F3FB6AD211A9D800A0C99B3E6F01B3DD70@TEAPHX0031> From: "TAZ Gravel, Emmanuel" To: "'freebsd-net@freebsd.org'" Subject: Socket programming, strange recv reaction Date: Mon, 23 Oct 2000 19:10:59 -0500 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2650.21) Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C03D4E.E868237A" X-SMTP-HELO: teaaushub001.telusa.com X-SMTP-MAIL-FROM: EGravel@taz.telusa.com X-SMTP-RCPT-TO: freebsd-net@freebsd.org X-SMTP-PEER-INFO: [172.17.40.252] Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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 #include #include #include #include #include #include #include #include #include #include #include #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); } } #include #include #include #include #include #include #include #include #include #include #include #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 Socket programming, strange recv reaction

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 =3D "Usage:\n\thello: = returns a message.\n\tquit: exits the session.\n";
  if ((numbytes =3D send(newfd, = msg, MAXBUFLEN, 0)) =3D=3D -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] =3D "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 =3D send(newfd, = msg, MAXBUFLEN, 0)) =3D=3D -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 =3D "Closing = connection. Goodbye!\n";
  printf("in = bye\n");
  if (send(newfd, msg, = sizeof(msg), 0) =3D=3D -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 =3D = socket(AF_INET, SOCK_STREAM, 0)) =3D=3D -1) {
        = perror("socket");
        = exit(1);
    }

    signal(SIGINT, = finalize);

    my_addr.sin_family = =3D AF_INET;         /* host = byte order */
    my_addr.sin_port = =3D htons(MYPORT);     /* short, network byte order = */
    = my_addr.sin_addr.s_addr =3D 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,
         &nb= sp;   sizeof(struct sockaddr)) =3D=3D -1) {
        = perror("bind");
        = exit(1);
    }

    if (listen(sockfd, = BACKLOG) =3D=3D -1) {
        = perror("listen");
        = exit(1);
    }

    children =3D = 0;

    while(1) {  /* = main accept() loop */
        sin_size =3D = sizeof(struct sockaddr_in);
       =20
        if (children < MAXCHILD) {
          if ((new_fd =3D accept(sockfd,
         &nb= sp;           &nb= sp;         (struct sockaddr = *)&their_addr,
         &nb= sp;           &nb= sp;         &sin_size)) = =3D=3D -1) {
            perror("accept");
            continue;
          }
          printf("server: got connection from = [%s]\n",
         &nb= sp;        = 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. */
         &nb= sp;  if (send(new_fd,
         &nb= sp;           = "Welcome to my world!\nWhat is your pleasure?\n",
         &nb= sp;           44, 0) = =3D=3D -1) {
              = perror("send");
              close(new_fd);
              exit(1);
            }
           
            while(1) {
             
              if ((numberbytes =3D = recv(new_fd,buf,MAXBUFLEN,0)) =3D=3D -1) {
        =         perror("recv");
        =         continue;
              }
             
              buf[numberbytes] =3D = '\0';

              printf("numberbytes = =3D [%i]\nbuffer =3D [%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] =3D "sta";
  struct hostent *he;
  struct sockaddr_in their_addr; = /* connector's address information */

  /*  printf("Before = init\n");
   */
  if (argc !=3D 2) {
    = fprintf(stderr,"usage: manuclient hostname\n"); /* put actual = error message here */
    exit(1);
  }
 
  /*printf("Before = gethostbyname\n");
   */
  if = ((he=3Dgethostbyname(argv[1])) =3D=3D 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 =3D = socket(AF_INET, SOCK_STREAM, 0)) =3D=3D -1) {
    = perror("socket");
    exit(1);
  }
 
  /* printf("Socket = created. Before socket connection.\n");
   */
  their_addr.sin_family =3D = AF_INET;         /* host byte = order */
  their_addr.sin_port =3D = htons(PORT);     /* short, network byte order = */
  their_addr.sin_addr =3D = *((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)) =3D=3D -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=3Drecv(sockfd, buf, MAXDATASIZE, 0)) =3D=3D -1) {
      = perror("recv");
      = exit(1);
    }

    printf("After = recv\n");

    buf[numbytes] =3D = '\0';
   
    = printf("Received: %s\n",buf);
   
    = printf("Command > ");
   
    = scanf("%s",msg);

    /*   if = (sizeof(msg) >=3D MAXDATASIZE)
      = msg[MAXDATASIZE] =3D '\0';
    */
    printf("Size = of message is %i\n",sizeof(msg));

    if ((numbytes =3D = send(sockfd, msg, MAXDATASIZE, 0)) =3D=3D -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-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message