CS640 Assignment 1 Hints and Tips


  1. Compiling:There are a few libraries required to actually compile and link the client and server programs.
    -lnsl is needed for calls like gethostbyname() .
    -lsocket is needed for socket calls. (Actually -lnsl is needed as well)
    -lpthread is needed for posix thread calls.
    -lposix4 is needed for semaphores.

  2. Always check the return values of system calls. For example
      if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) <0){
        perror("socket");
        exit(1);
      }
    
    Read the man pages of system calls carefully and make sure you understand the meaning of all the return values.

  3. Set the address size field in recvfrom() before calling it. For example
      cliAddrLen = sizeof(cliAddr);
      if ( (n = recvfrom(sd, (char*) data, sizeof(data), 0, &cliAddr,
                         &cliAddrLen)) < 0 )
        {
          ...
        }
    
    The cliAddr is just like a buffer you pass to the system requesting it to be filled in. You need to tell the system how large the buffer is, right? And since recvfrom() will change its value, it is better to set it every time recvfrom() is called.
    Note: the code used for the socket lecture in class did not do this, and consequently, would not work if compiled.

  4. Be sure you understand when to use network byte order.
    1. when specifying network addresses and ports
    2. when transferring integers, e.g., packet type if it is an integer.

  5. Be sure you know the uses of gethostbyname(), inet_ntoa() and inet_addr().
    1. gethostbyname()
      • returns struct hostent*
      • takes argument like "sun13.cs.wisc.edu"
    2. inet_addr()
      • returns unsigned long
      • takes argument like "128.105.40.13"
    3. inet_ntoa()
      • returns char * pointing to something like "128.105.40.13"
      • takes struct in_addr as an argument
    Example of using gethostbyname():
      struct hostent* server;
      struct sockaddr_in destAddr;
    
      /* argv[1] is "sun13.cs.wisc.edu" */
      if ( (server = gethostbyname(argv[1])) == NULL )
        {
          fprintf(stderr, "Cannot get address for host %s\n", argv[1]);
          exit(1);
        }
      memcpy(&(destAddr.sin_addr.s_addr), server->h_addr, server->h_length);
    
    Example of using inet_addr():
      struct sockaddr_in destAddr;
    
      destAddr.sin_addr.s_addr = inet_addr("128.105.40.13");
    
    Example of using inet_ntoa():
      // if added to the above inet_addr() code, this would print "128.105.40.13":
      //
      char *s = inet_ntoa(destAddr.sin_addr); 
      printf("dotted decimal address is %s\n", s);
    

  6. You need to use the exact packet structure as specified in the assignment. It is the basic requirement in the network world that everyone talks in the same language. Be sure you follow the specification requirement in the assignment.

  7. Don't bind() to a specific local address, instead, use INADDR_ANY. Some machines have more than one IP addresses. In general, your program will like to receive packets from all of them. So you cannot use a specific address. Try to look up the addresses of cisco-lab.cs.wisc.edu. See how many addresses you can find.

  8. Some students were not familiar with the following standard C/C++ functions which will be of use in the project. As noted, it is difficult to use the UNIX man facility if you do not know the name of commands, so here are a couple:
  9. memcpy - copies memory. Useful for building/parsing a packet in a buffer.
  10. memset - set a block of memory to some value. Usually for clearing memory

Last modified Sat Sep 02 13:30:05 1999 by Xiaohua Lu.