Thread: Need help with sending array of integers from client to server

  1. #1
    Registered User
    Join Date
    Feb 2020
    Posts
    5

    Need help with sending array of integers from client to server

    OS: Linux
    Language: C

    My client repeatedly sends arrays of integers to the server. The size of the array varies with each send from the client. The array of signed integers (defined as INT32) is packaged in the data_ptr variable and the array length is stored in the data_ptr_size variable. The first seven elements of the array are known to me so I use them to validate what the server is receiving.

    The issue I am having is that when I print out the first 7 array elements (integers) received by the server, they do not always match what the client has sent. However, I do believe the data is correct and in the order it was sent. For example, I know that data_ptr[0] always equals 999999999 and data_ptr[6] always equals -999999999.

    This issue has something to do with timing or maybe I need to do a handshake between messages. I appreciate your input.

    Client Side function to send array of integers to the server.
    Code:
    int send_packet(INT32 *data_ptr, INT32 data_ptr_size)
    {
        int hSocket;
        // Create socket
        hSocket = SocketCreate();
        if(hSocket == -1)
        {
            //printf("Could not create socket\n");
            return 1;
        }
        printf("Socket is created\n");
        
        // Connect to remote server
        if (SocketConnect(hSocket) < 0)
        {
            perror("connect failed.\n");
            close(hSocket);
            return 1;
        }
        printf("Sucessfully conected with server\n");
    
    
        // here send the size of the array
        if(send(hSocket,&data_ptr_size,sizeof(INT32),0) < 0)
        {
            printf("Send data_ptr_size Failed\n");
            close(hSocket);
            return 1;
        }
        printf("Send data_ptr_size Success\n");
    
    
        // here send the entire array
        if(send(hSocket, data_ptr, data_ptr_size*sizeof(INT32), 0) < 0) {
            printf("Send Failed\n");
            close(hSocket);
            return 1;
        }
    
    
        // print some info for verification purpose
        printf("size: %d %d\n",data_ptr_size,data_ptr_size*sizeof(INT32));
        printf("data_ptr[0]: %d\n",data_ptr[0]); // <--known value
        printf("data_ptr[6]: %d\n",data_ptr[6]); // <--known value
        printf("-------------------------------\n");
    
    
        close(hSocket);
        return 0;        
    }

    The server code is shown below:
    Code:
    int main(int argc, char *argv[])
    {
        INT32 *data_ptr = NULL;
        int socket_desc, sock, clientLen, read_size, array_size;
        int total = 0;
        struct sockaddr_in client;
        
        //Create socket
        socket_desc = SocketCreate();
        if (socket_desc == -1)
        {
            printf("Could not create socket");
            return 1;
        }
        printf("Socket created\n");
        
        // Bind
        if( BindCreatedSocket(socket_desc) < 0)
        {
            //print the error message
            perror("bind failed.");
            return 1;
        }
        printf("bind done\n");
        
        // Listen
        listen(socket_desc, 3);
        printf("Waiting for incoming connections...\n");
        
        // Accept and incoming connection.
        while(1)
        {
            clientLen = sizeof(struct sockaddr_in);
            // Accept connection from an incoming client
            sock = accept(socket_desc,(struct sockaddr *)&client,(socklen_t*)&clientLen);
            if (sock < 0)
            {
                perror("accept failed");
                return 1;
            }
            printf("Connection accepted\n");
            
        // read the size of array
        read_size = read(sock,&array_size,sizeof(INT32));
        if(read_size==0)
        {
                printf("error reading rec_val\n");
            exit(1);
        }    
            
        // create memory to store the array
        data_ptr = (INT32*)(malloc(array_size*sizeof(INT32))); 
        if(data_ptr==NULL)
        {
            printf("ERROR: memory failed to allocate.\n");
            exit(0);
        }
            
        
        // Read the array using the array size and data_ptr
        read_size = 0;
        total = 0;
    
    
        while ((read_size = recv(sock, (void *)data_ptr, array_size*sizeof(INT32), 0)) > 0) 
        { 
            total += read_size;
        }    
            
        // print out array information
        printf("size: %d %d\n",array_size,total);
            // the first 7 elements of the array are known and used of verification
        printf("data_ptr[0] : %d\n",data_ptr[0]);
        printf("data_ptr[1] : %d\n",data_ptr[1]);
        printf("data_ptr[2] : %d\n",data_ptr[2]);
        printf("data_ptr[3] : %d\n",data_ptr[3]);
        printf("data_ptr[4] : %d\n",data_ptr[4]);
        printf("data_ptr[5] : %d\n",data_ptr[5]);
        printf("data_ptr[6] : %d\n",data_ptr[6]);
        printf("-------------------------------\n");
        free(data_ptr);
        data_ptr=NULL;
            
            close(sock);
        }
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Sep 2020
    Posts
    122
    In the receiver, you have:


    Code:
      while ((read_size = recv(sock, (void *)data_ptr, array_size*sizeof(INT32), 0)) > 0) 
      { 
        total += read_size;
      }

    If you already have received data it will overwrite it, as data_ptr is always the same.


    You want to use something like this to advance the pointer forward.


    Code:
        recv(sock, ((void *)data_ptr)+total, (array_size*sizeof(INT32))-total, 0)

    And the while loop should be:


    Code:
      while(total != array_size*sizeof(INT32)) {
         ...
      }

    and the return from recv() should be used to trigger an exception (e.g. break out of the loop if it is < 1).




    Also, the code posted is only a fragment, so I can't build and test.
    Last edited by hamster_nz; 3 Weeks Ago at 02:39 PM.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,286
    The way you handle the return results of all your send/recv calls are wrong.

    Neither guarantee complete success or complete failure. You have to deal with partial success as well.

    n = send(sock,"hello",5);
    If n is 5, you're good.
    But if n were 3 say, then it's up to you to then call send again with
    n = send(sock,"lo", 2);

    Some simple code to send a buffer, possibly over multiple calls to send.
    Code:
    int mySend(int sock, const void *buff, size_t bsize ) {
      const char *bp = buff;
      int n;
      while ( (n=send(sock,bp,bsize)) > 0 ) {
        bp += n;
        bsize -= n;
      }
    }

    Same on the receive side.
    There is no information in the received packet sizes about how the other end called send.
    You specifically cannot assume that send("hello") will always result in a single recv call returning "hello".
    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.

  4. #4
    Registered User
    Join Date
    Feb 2020
    Posts
    5
    Quote Originally Posted by hamster_nz View Post
    In the receiver, you have:


    Code:
      while ((read_size = recv(sock, (void *)data_ptr, array_size*sizeof(INT32), 0)) > 0) 
      { 
        total += read_size;
      }

    If you already have received data it will overwrite it, as data_ptr is always the same.


    You want to use something like this to advance the pointer forward.


    Code:
        recv(sock, ((void *)data_ptr)+total, (array_size*sizeof(INT32))-total, 0)

    And the while loop should be:


    Code:
      while(total != array_size*sizeof(INT32)) {
         ...
      }

    and the return from recv() should be used to trigger an exception (e.g. break out of the loop if it is < 1).




    Also, the code posted is only a fragment, so I can't build and test.

    Obviously I'm still learning C so please forgive my ignorance. I can't post the entire client side code since is huge. But I may be able to mock something up to demonstrate the client side data structure better. I thought that the pointer data_ptr would advance forward as new data comes in. I will experiment with your suggestions tomorrow and reply back. I greatly appreciate your advise.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. basic TCP client/server not sending file from virtual machine to host pc
    By Anddos in forum Networking/Device Communication
    Replies: 4
    Last Post: 02-23-2012, 05:33 PM
  2. Client/server problem; server either stops receiving data or client stops sending
    By robot-ic in forum Networking/Device Communication
    Replies: 10
    Last Post: 02-16-2009, 11:45 AM
  3. Replies: 2
    Last Post: 07-24-2008, 06:05 AM
  4. sending binaries files between server and client
    By nacho4d in forum C Programming
    Replies: 12
    Last Post: 01-31-2008, 01:54 AM
  5. Replies: 2
    Last Post: 11-23-2007, 02:10 AM

Tags for this Thread