Thread: Sockets: send/receive continuous stream of data?

  1. #1
    Registered User
    Join Date
    Jul 2002
    Posts
    44

    Sockets: send/receive continuous stream of data?

    Hey all,

    I'm trying to create a TCP client app and TCP server app using C (sockets w/ linux and winsock with windows)

    I think I have the opening/closing sockets part down for both apps. The problem I'm facing is figuring out how to send and receive the data. The info to be sent is a series of ever changing number values. To emulate what I'd actually need I was thinking I could create an endless loop that sent random number data (client end) to the server. Right now I'm only trying to send individual strings typed in by the user...however, I don't think I have a good idea of how to really put the data into a buffer to send and receive it.

    Also really quick question... whenever I call accept(), subsequent terminal output becomes all weird. I need to specify a newline before and after each statement I printf or wierd stuff happens. Namely, I'll get a newline but no text. Any ideas why?

    It'd be awesome if someone can help me create a skeleton for send/recv or give me a conceptual description of how to set up send/rcv for my situation. The code I've attached is for rx and tx (only the relevant portion of the application's code)... let me know if the rest is necessary.


    Code:
    //from client app (winsock)
        //____________________________________________
        // SEND data
        char *txMsg = "Hello World!";
        vRet = send (dataTx, txMsg, (int)strlen(txMsg), 0);
       
        if (vRet == SOCKET_ERROR)
        {
            cout << "\nError sending data... Exiting";
            cout << "\nsend failed with error: " << WSAGetLastError();
            cout << "\n";
            system("PAUSE");
            closesocket(dataTx);
            return 0;
        }
    
        else
        {
            cout << "Sent data.\n";
            //return 0;
        }


    Code:
    //from server app
        {
            //the accept function waits if there are no pending connections
            dataTx = accept (dataRx, (struct sockaddr*)&remote, &remLen );
    
            printf("\n");
            printf("-> [Connected to client %s]", inet_ntoa(remote.sin_addr) );
            printf("\n");
            
            do
            {
                char *recvBuff;
                recvBuff = malloc (4 * sizeof(char));
                
                if (numBytes = recv (dataTx, recvBuff, recvBuffSize, 0) > 0)
                {
                    printf("\n-> Bytes Received: %d \n", numBytes);    //why always one?
                    printf("\n-> Message Received: %s \n", recvBuff);
                    
                    if (!(strcmp(recvBuff, quitString)))
                        {   printf("\nshould quit\n");
                            exFlag = 1;     }
                            
                    free (recvBuff);
                    recvBuff = NULL;
                }
                
                
            } while (exFlag != 1);
            
            
            printf("\n-> [Closed connection]\n");
            
            close(dataTx);
        }

    Thanks!
    d02

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > vRet = send (dataTx, txMsg, (int)strlen(txMsg), 0);
    You also need to take account of vRet > 0 && vRet < (int)strlen(txMsg)
    In other words, don't assume that a large message will always be transmitted in a single call.

    > recvBuff = malloc (4 * sizeof(char));
    What has 4 got to do with say recvBuffSize ?

    > if (numBytes = recv (dataTx, recvBuff, recvBuffSize, 0) > 0)
    You've written this
    if (numBytes = (recv (dataTx, recvBuff, recvBuffSize, 0) > 0))
    You probably want this
    if ((numBytes = recv (dataTx, recvBuff, recvBuffSize, 0)) > 0)
    Check your operator precedence table.

    > printf("\n-> Message Received: %s \n", recvBuff);
    recv knows nothing about the data, so there will be no \0 at the end of every received fragment.
    One way would be to do say
    printf("\n-> Message Received: %.*s \n", numBytes, recvBuff);

    Another way, allow room in the buffer to append a \0, then use numBytes to place a \0 in the correct place to make it a proper string.

    > if (!(strcmp(recvBuff, quitString)))
    Like sending, receiving can also fragment data. Reassembling the stream is your problem.
    For example, in two successive calls, you might get "qu" then "it".
    The result is what you want, but your simple test fails.
    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. Pipe class.
    By eXeCuTeR in forum Linux Programming
    Replies: 8
    Last Post: 08-21-2008, 03:44 AM
  2. data structure design for data aggregation
    By George2 in forum C# Programming
    Replies: 0
    Last Post: 05-20-2008, 06:43 AM
  3. Replies: 3
    Last Post: 04-18-2008, 10:06 AM
  4. Sockets switching data?
    By b00l34n in forum Networking/Device Communication
    Replies: 5
    Last Post: 02-15-2005, 01:03 PM
  5. How do I base size of arrays on annother number?
    By Dual-Catfish in forum C++ Programming
    Replies: 15
    Last Post: 09-25-2001, 01:31 PM