0

I have server client application. When I'm sending messages in a row(without scanf in the code below), it's seems the server doesn't get them(doesn't print). if I wait a little bit(with the scanf in the code below) and then send the next message the server works fine and prints all messages.

what's the problem? how can I fix it, cause I want to do more with the message(not just to print it) that arrived to the server.

in my client code(where server prints nothing)

char message[(100)] = {0};
int x = rand();
while(i < 3)
    {
        printf(" I send %d\n", x);fflush(NULL);
        sprintf(message, "%d",x);
        if( send(mainSockfd, message,strlen(message),0) == -1)
        {
            printf("ERRRRRORRRR\n");fflush(NULL);
        }
        i++;
        x = rand() % 100;
    }

in my client code(when server prints the messages)

char message[(100)] = {0};
int x = rand();
while(i < 3)
{
    printf(" I send %d\n", x);fflush(NULL);
    sprintf(message, "%d",x);
    if( send(mainSockfd, message,strlen(message),0) == -1)
    {
        printf("ERRRRRORRRR\n");fflush(NULL);
    }
    i++;
    x = rand() % 100;
    scanf("%d",&x); // this is the only change
}

in my server code

char command[(100+1)] = {0};
while(1)
    {
        readLength = recv(sockfd, command, 100+1,0);
        if(readLength > 0)
        {
            printf("arrived = %s,\n",command);fflush(NULL);
            ZeroMemory(command, sizeof(command));
        }
        else if( readLength == 0)
                {
                    break;
                }
        else if ( readLength < 0 ){
            if(GetLastError() == 10035)
            {
                continue;
            }
            if(GetLastError() == 10057 || GetLastError() == 10054)
            {
                break;
            }
            continue;
        }
    }
Kobi Guetta
  • 105
  • 2
  • 8
  • How is `command` declared? What is `MAX_MSGLEN`? Also print `readLength`. How is `message` declared? – alk Aug 25 '14 at 13:36
  • I edited. readLength is -1 when the connection is closed. in the code without the scanf nothing is printed(I tried to print readLength also). – Kobi Guetta Aug 25 '14 at 14:21
  • "*readLength is -1*" and which error do you get by `GetLastError()`? – alk Aug 25 '14 at 14:31
  • 10054.. it's happens when the client finished sending his messages and closed the connection – Kobi Guetta Aug 25 '14 at 14:34
  • You can break the loop if when `recv()` had returend `0`, as this means the other closed the connection. Please read here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740121%28v=vs.85%29.aspx – alk Aug 25 '14 at 14:43
  • I tried but it never broke out, so I printed and I found it was readLength -1 with GetLastError = 10054. so readLength=0 actually never happend to me in the server. – Kobi Guetta Aug 25 '14 at 15:35
  • The sender should not close a socket connection until the transmit has completed. I.E. You should wait for the EPOLLOUT event on your socket descriptors, using the epoll_wait() function: – user3629249 Aug 26 '14 at 03:44
  • @user3629249 - and in windows(winsock)? – Kobi Guetta Aug 26 '14 at 10:08
  • @user3629249: After a succesful `send()` it is perfectly fine for the sender to `close()` the socket through which the data was sent. The OS takes care of any pending data transmissions. – alk Aug 27 '14 at 16:31
  • "*... I found it was readLength -1 with GetLastError = 10054. so readLength=0 actually never happend to me in the server.*": You shall call `close()` any open socket before the program exits. Receiving 10054 on the server side is a strong hint the client ended without having `close()`ed the sending socket. Please RTFM here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx – alk Aug 27 '14 at 16:32

1 Answers1

1

As you seem to be transferring 0-terminated "strings" without the 0 termination, you should read one char less then the read buffer provides to always have the read buffer being 0-terminated, as if you try to printf a non 0-terminated "string" you provoke undefined behaviour.

So change this

readLength = recv(sockfd, command, 100+1,0);

to become this

readLength = recv(sockfd, command, 100,0);
alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    Yup - it's a classic. Abuse of strlen() in network code #0193473 :) – Martin James Aug 25 '14 at 15:34
  • now I'm getting the first message ok, and the other 2 concatenated. i'm sending 41 67 and 34. the first message is "arrived = 41,", the second one is "arrived = 6734," and the third is "arrived = ," – Kobi Guetta Aug 25 '14 at 16:08
  • @KobiGuetta: Ok, so this is a different issue. For which you might like to pose another question. Also reading this answer http://stackoverflow.com/a/24536689/694576 might help you to understand what is happening. – alk Aug 25 '14 at 16:22
  • it is matter if I'm using Winsock function such as WSArecv or maybe using the events(FDSET etc)? I never tried to use them. – Kobi Guetta Aug 26 '14 at 10:10
  • @alk: I've changed in send function, from strlen(message) to 100, and now it's never concatenated and it prints fine but there is times it's print nothing(readLength is -1). – Kobi Guetta Aug 26 '14 at 19:49