Thread: Socket programming

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    17

    Socket programming

    I'm trying to type a socket program that will allow me to transfer a file between a client and a server on two different computer, but it's not working. What's wrong with the code???

    Server

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/wait.h>
    #include <signal.h>
    #include <errno.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    void sigusr1_handler(int sig)
    {}
    
    void sigchldhandler(int sig)
    {
      while (waitpid(-1,0,WNOHANG) > 0);
    }
    
    int main(int argc, char * argv[])
    {
      int serversockfd, clientsockfd, clientaddrlen, match;
      struct sockaddr_in serveraddr, clientaddr;
      struct sigaction act;
      char buffer[1000];
      char direction[4];
      char filepath[100];
      char * address=argv[1];
      char * port=argv[2];
    
      if(argc!=3)
      {
        printf("Incorrect number of arguments.");
        exit(1);
      }
    
      /*defines handler for SIGCHLD to prevent zombie processes*/
      act.sa_handler = sigchldhandler;
      sigemptyset(&act.sa_mask);
      act.sa_flags=SA_RESTART;
      sigaction(SIGCHLD, &act, 0);
      
      /*defines handler for SIGUSR1*/
      act.sa_handler = sigusr1_handler;
      sigemptyset(&act.sa_mask);
      act.sa_flags = 0;
      sigaction(SIGUSR1, &act, NULL);
    
      /*create server socket*/
      serversockfd=socket(AF_INET, SOCK_STREAM, 0);
      serveraddr.sin_family=AF_INET;
      serveraddr.sin_addr.s_addr=inet_addr(address);
      serveraddr.sin_port=atoi(port);
    
      /*bind address to socket and listen for connections*/
      bind(serversockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
      listen(serversockfd, 5);
      
      while(1)
      {
        printf("Waiting for connection...\n");
        
        /*accept client connection*/
        clientaddrlen=sizeof(clientaddr);
        clientsockfd=accept(serversockfd,(struct sockaddr *)&clientaddr, &clientaddrlen);
        printf("Connection accepted\n"); 
       
        /*fork child process to allow multiple connections*/
       
        if((fork())==0)
        {
          /*receive information from client regarding direction and filepath*/
          printf("Server: Waiting for client's info\n");
          int * clid, seid = getpid();
          read(clientsockfd, clid, sizeof(clid));
          write(clientsockfd,&seid,sizeof(seid));
          read(clientsockfd, direction, sizeof(direction));
          read(clientsockfd, filepath, sizeof(filepath));
          printf("Server: Got info from client\n");
    
          /*GET*/
          if(strcmp(direction,"GET")==0)
          {
            printf("Server: Get\n");
            FILE * in;
            if((in=fopen(filepath, "r"))==NULL)
            {
              fprintf(stderr,"File does not exist");
              char * err="Error: File did not exist on server.";
              write(clientsockfd,err,strlen(err)+1);
              exit(1);
            }
              
            while(fgets(buffer,sizeof(buffer), in)>0)
            {
    	   write(clientsockfd,buffer,strlen(buffer)+1);
    	   kill((int)clid, SIGUSR2);
    	   pause();
            }
                   
            fclose(in);
          } 
    
          /*PUT*/
          else if(strcmp(direction,"PUT")==0)
          {
            printf("Server: Put\n");
            FILE * out = fopen(filepath, "w");
            while(match>0)
            {
    	  pause();
    	  match = read(clientsockfd,buffer,sizeof(buffer));
              fwrite(buffer, 1, strlen(buffer), out);
              kill((int)clid, SIGUSR2);
            }
            fclose(out);
          }
          /*bad input*/
          else
          {
            close(clientsockfd);
            exit(1);
          }
          
          close(clientsockfd);
          exit(0);
        }
        else
          close(clientsockfd);
      }
    }
    Client

    Code:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <signal.h>
    
    void sigusr2_handler(int sig)
    {}
    
    int main(int argc, char *argv[])
    {
      int sockfd;
      char *match;
      struct sockaddr_in serveraddr;
      struct sigaction act;
      char* addr = argv[1];
      char* port = argv[2];  
      char* direction = argv[3]; /*GET or PUT*/
      char* filepath = argv[4];
    
      char buffer[1000];
    
      /*defines handler for SIGUSR2*/
      act.sa_handler = sigusr2_handler;
      sigemptyset(&act.sa_mask);
      act.sa_flags = 0;
      sigaction(SIGUSR1, &act, NULL);
     
      if(argc!=5)
      {
        printf("Incorrect number of arguments");
        exit(1);
      }
      sockfd=socket(AF_INET,SOCK_STREAM,0);
    
      serveraddr.sin_family=AF_INET;
      serveraddr.sin_addr.s_addr=inet_addr(addr);
      serveraddr.sin_port=atoi(port);
    
      if(connect(sockfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
      {
        perror("Connection failed\n");
        exit(1);
      }
      
      /*FTP*/
      
      /*sends to server GET or PUT and the filepath*/
      printf("Client: Sending info to server\n");
      int* seid, clid=getpid();
      write(sockfd,&clid,sizeof(clid));
      read(sockfd,seid,sizeof(seid));
      write(sockfd,direction,strlen(direction)+1);
      write(sockfd,filepath,strlen(filepath)+1);
      printf("Client: Info sent\n");
       
      /*GET*/
      if(strcmp(direction,"GET")==0)
      {
        printf("Client: Get file\n");
        FILE * out = fopen(filepath,"w");
        while(read(sockfd, buffer, sizeof(buffer))>0)
        {
           pause();
           fwrite(buffer, 1, strlen(buffer), out);
           kill((int)seid, SIGUSR1);
        }
        fclose(out);
      }
    
      /*PUT*/
      else if(strcmp(direction,"PUT")==0)
      {
        printf("Client: Put file\n");
        FILE * in;
        if((in=fopen(filepath, "r"))==NULL)
        {
          fprintf(stderr,"File does not exist.\n");
          exit(1);
        }
        while(match!=NULL)
        {
          match = fgets(buffer, sizeof(buffer), in);
          write(sockfd,buffer,strlen(buffer)+1);
          kill((int)seid, SIGUSR1);
          pause();
        }
        fclose(in);
      }
    
      else
      {
        perror("Invalid command\n");
        close(sockfd);
        exit(1);
      }
    
      close(sockfd);
      exit(0);
    }

  2. #2

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    17
    It's printing (whenever I can get to print) random lines.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Step 1 is learn what is safe to call in a signal handler, and what isn't.
    http://www-128.ibm.com/developerwork...nxw16Reentrant
    A while loop calling wait inside a signal handler isn't.

    Short, with minimal impact on the system and using very few system calls characterise most signal handlers.
    Calling wait() in a loop doesn't seem to me to be in the ball park.

    > read(sockfd,seid,sizeof(seid));
    Where is that pointing? - nowhere in particular.

    > fwrite(buffer, 1, strlen(buffer), out);
    read() does NOT append a \0, so you can't use strlen to decide how much to write.
    Further, and this applies to all your read/write calls, you don't check for errors, and you don't check that what you asked to happen actually happened.

    Both sending and receiving can fragment the data, and it's up to you to deal with it.

    > while(match!=NULL)
    Since you don't initialise this, how can you compare with it?

    > kill((int)clid, SIGUSR2);
    What the hell is this supposed to do?
    If the client and server are on different machines, there's no way that this is going to work.
    If by some stroke of luck you have the same PID on both machines, it isn't going to be the PID of the partner process.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. socket programming question, closing sockets...
    By ursula in forum Networking/Device Communication
    Replies: 2
    Last Post: 05-31-2009, 05:17 PM
  2. Socket Help - Multiple Clients
    By project95talon in forum C Programming
    Replies: 5
    Last Post: 11-17-2005, 02:51 AM
  3. when to close a socket
    By Wisefool in forum Networking/Device Communication
    Replies: 5
    Last Post: 11-02-2003, 10:33 AM
  4. problem closing socket
    By Wisefool in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-29-2003, 12:19 PM
  5. socket newbie, losing a few chars from server to client
    By registering in forum Linux Programming
    Replies: 2
    Last Post: 06-07-2003, 11:48 AM