Socket server sends text, client gets cut off or twisted...Problem with sock recv() queue?

Hi, I have a server right now that sends text to my client very fast, and the problem is, is that the client gets text, but not all of it, and often mangled so that there are duplicates of what is sent once. I am thinking that this is a problem with that when the server sends the text, the client is not recieving it fast enough and it only gets half of it or something. However, I have read up on it, and I have seen that when a message it sent from a Sock to a Sock, and the listening socket is not currently using recv(), then it just waits until it does, and the information being sent just "stacks" up. Any help? Thanks.
Matthew

Snippet of Source
SERVER
Init of Socket and listen/accept ing
       int RetVal;
        SOCKET Sock;
        SOCKADDR_IN SockAddr;
        Sock = socket(AF_INET, SOCK_STREAM, 0);
        if(Sock == INVALID_SOCKET)
        {
           //MessageBox(NULL, "Invalid Socket", "ERROR", MB_OK);
           return;
        }
        SockAddr.sin_port = htons(listen_port);
        SockAddr.sin_family = AF_INET;
        SockAddr.sin_addr.s_addr = INADDR_ANY;
        if(bind(Sock, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
        {
            //MessageBox(NULL, "SocketBind", "ERROR", MB_OK);
            PostQuitMessage(1);
        }
        //setsockopt(Sock, SOL_SOCKET, SO_REUSEADDR, 1, sizeof(int))
        listen(Sock, 10);
        SOCKET TempSock = SOCKET_ERROR;
        while(TempSock == SOCKET_ERROR && con != 1)
        {
            TempSock = accept(Sock, NULL, NULL);
        }
Then it goes on to send info like this...
send(Sock, "hello there", 12, 0);
send(Sock, "\nMy name is Matthew", 20, 0);
send(Sock, "\nI like pie...", 15, 0);
send(Sock, "\nPlease give me cheese and I will thank you", 44, 0);



CLIENT
As Global Vars
SOCKET Sock;
SOCKADDR_IN SockAddr;

       SockAddr.sin_port = htons(7777);
       SockAddr.sin_family = AF_INET;
       SockAddr.sin_addr.s_addr = INADDR_ANY;
       if(bind(Sock, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)
       {
                cout << "Attempt to bind failed! Try a different Port..." << endl;
       }
       listen(Sock, 1);
       cout << "Listening..." << endl;
       cout << endl;
       SOCKET TempSock = SOCKET_ERROR;
       //SOCKADDR_IN sckadr;
       while(TempSock == SOCKET_ERROR)
       {
           TempSock = accept(Sock, NULL, NULL);
       }
       Sock = TempSock;
       cout << "\a\a\a\aIncoming Connection Accepted..." << endl;

Then it starts recieving messages in a separate thread while "cin" ing for messages to send to server (which also listens for messages in this same way)...
int RetVal;
char mesg[256];
while(TRUE)
{
        RetVal = recv(Sock, (char*)mesg, 256, 0);
        if((RetVal == 0) || (RetVal == WSAECONNRESET))
        {
            closesocket(Sock);
            cout << "Connection Terminated...";
            char tm[15];
            SYSTEMTIME st;
            GetLocalTime(&st);
            if(GetTimeFormat(LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &st, NULL, tm, 15))
               cout << "(" << tm << ")";
            cout << endl;
               return;
        }
        else if(RetVal != SOCKET_ERROR)
        {
            cout << mesg;
        }
        else if(RetVal == SOCKET_ERROR)
        {
            cout << "Connection Terminated...";
            char tm[15];
            SYSTEMTIME st;
            GetLocalTime(&st);
            if(GetTimeFormat(LOCALE_SYSTEM_DEFAULT, LOCALE_NOUSEROVERRIDE, &st, NULL, tm, 15))
                  cout << "(" << tm << ")" << endl;
            cout << endl;
            closesocket(Sock);
            return;
        }
}
return;
BlakIXEAsked:
Who is Participating?
 
mxjijoConnect With a Mentor Commented:

itsmeandnobodyelse,
    I guess BlakIXE's method also would work, because it looks like he is printing whatever he receives
before he calls the next recv. So even if there are 1000 bytes in the the TCP buffer, he can very well recv
blocks of 256 and display it without a problem.

    I guess BlakIXE's problem is even simpler, you have to put a '\0' at the end of all received buffer before you print it out. If you dont have \0 then out cout will print the whole buffer until it fins a \0.

Try this
       else if(RetVal != SOCKET_ERROR)
        {
            mesg [RetVal] = 0;            // <--------------- add this line.
            cout << mesg;
        }

~j
0
 
itsmeandnobodyelseConnect With a Mentor Commented:
The client must not call bind(), listen() and accept() but connect() to the server's IP and port.

A successful connect() of the client will occur if  the server has a successful accept().

Tell me, if you need more info.

Regards, Alex


0
 
BlakIXEAuthor Commented:
Yea, sorry about the misinformment thing.
  Both Client and Server listen and connect. Wierd eh?
  But it works to connect an all.
  The problem is the garbled and jumbled text.

BlakIXE
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
itsmeandnobodyelseCommented:
1. You should post the connect() code also ...

2. I can see more than one send(..) but only one recv(). After that the connection is closed
    throwing away any further message(s)...

Regards, Alex
0
 
itsmeandnobodyelseCommented:
>> The problem is the garbled and jumbled text.

You have a 256 byte buffer that you fill with using that while(TRUE) loop. But you don't save the text read somewhere but the next recv() overwrites the contents previously read.

    RetVal = recv(Sock, (char*)mesg, 256, 0);          // second read overwrites first read

So you should do something like this:

   char msg[4096];  // Make a big buffer
   int received = 0;

   while(TRUE)
   {
           RetVal = recv(Sock, &msg[received], 4096 - received, 0);
           if (RetVal > 0)
           {
                received += RetVal;
           }
           else if (...
           {
           }        
   }

Regards, Alex

       
0
 
itsmeandnobodyelseCommented:
mxjijo,

you are right: there is a  'printing' on cout after reading successfully. Maybe it should be written to a file also, as cout's from a thread may get improperly outputted.

if the socket is non-blocking the socket most likely returns with SOCKET_ERROR and WSAEWOULDBLOCK. If not it waits til the socket is disconnected by the client or is broken. A RetVal of  0 only is returned if the client gracefully terminated the connection using a shutdown() and a sufficient wait time before closesocket(). A RetVal of WSAECONNRESET never is returned as all WSA errors only could received only by calling WSAGetLastError() after a returned RetVal of SOCKET_ERROR.

A terminating zero to the char buffer received must be added only if the send messages cut the zero character. However, the send statements posted above all include a zero character.

Regards, Alex
0
 
mxjijoCommented:

hey..... hold on ...

are you using non-blocking sockets ?? where do you handle  WSAEWOULDBLOCK ??

Also I think in the above messages where you have a \n in front you need to send one more character
to get to th \0 at the end. Did I count them correct ?

Use
sendto (socket, "whatever", strlen ("whatever") + 1, 0);

0
 
BlakIXEAuthor Commented:
Well, I added one extra length thing for the text I was sending, and that worked to stop it adding text to the end of messages....However, text is still not getting through. I will try sending it to a file first to see if cout is the problem, but I don't think it is.
I have a "dir" command, that gets the files in the current directory, and when I test it on my computer, (both client and server on same computer) it works great!, however, when I try to use the server on a different machine over a network, the directory command fizzles and screws with the text, so the problem is still there. I will do the file thing and check back with you guys, thanks a bunch.

BlakIXE
0
 
BlakIXEAuthor Commented:
oh yea, no, I am not using non-blocking
0
 
itsmeandnobodyelseCommented:
Did you call WSAGetLastError() to get the specific socket error different from SOCKET_ERROR == -1 ?

What OS has the remote server? Same as your's? Or do you have a Little-Endian / Big-Endian connection?

Regards, Alex
0
 
mxjijoCommented:

Okay.. now I guess whatever you receive is not getting mangled. - good.
Now to the other missing text problem.
There are a few methods to isolate the problem.

1) Check out the error code and make sure the number of bytes sent is correct.

2) Use a sniffer (Ethreal or MS network monitor) and see what happens to the packet / dest IP/ port number etc)
   You may use TDIMon.exe from sysinternals as well.

Still if you use UDP there is no guarentee that the packet will make it over to the other end.
Use UDP only if it is absolutely necessary (line streaming / broadcasting etc)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.