Thread: Client-server system with input from separate program

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    12

    Client-server system with input from separate program

    Hi, this is my first time posting here.

    I'm working together with a couple of other people on a project where one program takes input from an external device, and from there the values that program has received are to be transferred over the local network to another computer.

    I'm tasked with setting up the communication between the two computers. I set up a tcp-ip client server system to connect the two computers and send the data, and that wasn't much of a problem. What I've been working on since has been getting the data from the program which receives the data into my client program. I decided to try spawning my client program from the original program, then setting up a pipe that would write the values to my client program. I spawn tested the spawn and pipe functions with a simple program that
    would take a string, spawn a second program, pipe the string to the second program, and then print the string to the screen from the second program.

    My next test was to modify my spawn and pipe example by then having the second program print the test string, then connect to another computer and send the string over the network. Unfortunately, now I have a problem:
    Apparently the spawned program is trying to read from the pipe before the parent program writes to it, because it is printing out junk data.

    Is there some way I can fix this, maybe to make the program continually read from the pipe at a certain interval, and to print/send data only when a non junk value is read?

    Here is my code for the parent program:
    Code:
    #include <stdio.h>
    #include <process.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <fcntl.h>
    #include <io.h>
    
    #define inpipe 11
    #define outpipe 12
    
    int main()
    {
        int pipes[2];
        char outbuf[512], inbuf[512];
       
        /* Open a set of pipes */
          if( _pipe( pipes, 256, O_BINARY ) == -1 )
              exit( 1 );
              
        _dup2(pipes[0], inpipe);
        _dup2(pipes[1], outpipe);
        strcpy(outbuf, "This is a test of pipes.\n");
        
    	
        int pid;
        char *file = "client3.exe";
        printf("About to open child program \n");
        pid = _spawnl( P_NOWAIT,"client3.exe",file);
        
        if (_write(outpipe, outbuf, strlen(outbuf) + 1) == -1) {
                perror("Parent - Write failed");
                exit(EXIT_FAILURE);
            }
    //getchar();
    return 0;
    
    }
    and for my child program:
    Code:
    #include <stdio.h>
    //#include <unistd.h>
    //#include <perror.h>
    #include <process.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <fcntl.h>
    #include <io.h>
    #include <winsock2.h>
    
    
    #define inpipe 11
    #define outpipe 12
     
    
    int client()
    
    {
    
      // Initialize Winsock
    
      WSADATA wsaData;
    
      int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    
      if (iResult != NO_ERROR)
    
        printf("Client: Error at WSAStartup().\n");
    
      else
    
        printf("Client: WSAStartup() is OK.\n");
    
     
    
      // Create a SOCKET for connecting to server
    
      SOCKET ConnectSocket;
    
      ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
      if (ConnectSocket == INVALID_SOCKET)
    
      {
    
        printf("Client: Error at socket(): %ld\n", WSAGetLastError());
    
        WSACleanup();
    
        return 0;
    
      }
    
      else
    
             printf("Client: socket() is OK.\n");
    
     
    
      // The sockaddr_in structure specifies the address family,
    
      // IP address, and port of the server to be connected to.
    
      sockaddr_in clientService;
       //hostent* remoteHost;
    
    char* ip;
    
    char* host_name;
    
    unsigned int addr;
    char buffer[512];
    int len;
     
     printf("Child - Reading from parent\n");
     if ((len = read(inpipe, buffer, 512)) <= 0) {
            perror("Child - Read failed");
            exit(EXIT_FAILURE);
        }
        else {
            printf("Child: %s\n", buffer);
           
        
    
    // User inputs name of host
    
    printf("Input IP of the host: ");
    
    ip = (char*) malloc(sizeof(char*)*128);
    
    fgets(ip, 128, stdin);
    //addr = inet_addr(host_name);
     
    
    
    
    
      
    	clientService.sin_family = AF_INET;
    	clientService.sin_port = htons(55555);
    	clientService.sin_addr.s_addr = inet_addr(ip);
    
    
      
      
    
     
    
      // Connect to server...
    
      if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
    
      {
    
        printf("Client: Failed to connect.\n");
    
        WSACleanup();
    
        return 0;
    
      }
    
      else
    
           printf("Client: connect() is OK.\n");
    
     
    
      printf("Client: Connected to server...\n");
       // Send and receive data.
    
        int bytesSent;
    
        int bytesRecv = SOCKET_ERROR;
    
        
    
        char sendbuf[200]; 
    	//= "Client: Sending some test string to server...";
    
        char recvbuf[200] = "";
    
    	
    
     
    
        bytesSent = send(ConnectSocket, sendbuf, strlen(sendbuf), 0);
    
        printf("Client: send() - Bytes Sent: %ld\n", bytesSent);
    
     
    
        while(bytesRecv == SOCKET_ERROR)
    
        {
    
            bytesRecv = recv(ConnectSocket, recvbuf, 32, 0);
    
            if (bytesRecv == 0 || bytesRecv == WSAECONNRESET)
    
            {
    
                printf("Client: Connection Closed.\n");
    
                break;
    
            }
    
            else
    
                printf("Client: recv() is OK.\n");
    
     
    
            if (bytesRecv < 0)
    
                return 0;
    
            else
    
                printf("Client: Bytes received - %ld.\n", bytesRecv);
    
        }
    
    
      WSACleanup();
    
      return 0;
    
    }
    Thanks for reading!

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Why don't you just use an identical program on both the local and remote machine (lets call that "server to server") and then just use a socket, rather than a pipe, since you aren't having any problems with sockets and they are much better for this anyway? Then the local server will have two connections -- one to the remote machine, and one to the local program that gathers the information.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    12
    First, thanks for replying.

    Do you mean using the program that gets the original input on two computers? If so, that unfortunately isn't an option based on what we're trying to accomplish.

    I was trying to implement my part of the system with minimal editing of the guy I'm working with's program, but now I'm thinking that maybe I should try making my client program separate thread in the original program. Do you think that would work?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    Post

    Well, the only thing I've done with sockets that involves both ends of a client/server operation, beside some exercises and experiments, is a forked local unix socket server that's part of a GUI text viewer app. Altho it's all one program, it's not threaded, it's forked, which means the child process operates as a server and maintains a local socket connection to it's parent process, because it must function in it's own loop to accept connections independent of the GUI (which a GUI also runs using a loop, and threads). The GUI loop is no good for "server" type operations -- listening on a socket for connection requests -- but it's fine for monitoring an established connection. When the application is first invoked, it checks a to see if a unique socket (a socket only ever used by that application) exists, and if so, checks to see if there is a running server accepting connections on the socket. If so, it passes it's command line arguments on and exits without ever starting the GUI. Your web browser probably works this way, so if it's running and you type:

    firefox www.cprogramming.com

    or click an url in some other program somewhere, rather than start a second instance of the application, the information gets passed along to the first instance by a forked server, which is a child of that instance. If you check your running processes, you will see two of them listed although only one is performing functions directly involving the end-user. They are actually using different amounts of the memory and processor, since the child first shuts down it's copy of the GUI (and other now irrelevent things) before starting the server, while the parent only has to run in client mode.

    My point is that when you write "Do you mean using the program that gets the original input on two computers? If so, that unfortunately isn't an option based on what we're trying to accomplish." I can't really assume this is true since I don't know completely what you are trying to accomplish, but based on what you have said so far in this thread I would say the best idea is to write one multi-threaded or forking program that can perform all the necessary performances relative to the context it's operating "in". Since the server process will be listening on an actual internet socket, the parent process which does the local information processing will have to contact it's child (the server) at the address where it is also waiting for a connection request from another instance of the server, running on another machine and connected to a parent that is presenting the information.

    That's one program, not two or four or three.
    Last edited by MK27; 01-16-2009 at 03:35 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Chat Program Help?
    By Paul22000 in forum Networking/Device Communication
    Replies: 9
    Last Post: 02-10-2009, 12:35 AM
  2. Socket Programming Problem!!!!
    By bobthebullet990 in forum Networking/Device Communication
    Replies: 2
    Last Post: 02-21-2008, 07:36 PM
  3. my server program auto shut down
    By hanhao in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-13-2004, 10:49 PM
  4. Server Client Messaging Program
    By X PaYnE X in forum Networking/Device Communication
    Replies: 3
    Last Post: 01-04-2004, 05:20 PM
  5. socket question
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 07-19-2002, 01:54 PM