2

I've a problem with recv() function that I can't explain: it always returns 0. I've a client/server application in which the server simply has to receive a string from the client through the internet (different pc).
There are no connectivity problems, and I also tried to send a string from server to client: it worked. I search in the blog and what I found, recv() socket function returning data with length as 0, non-blocking recv returns 0 when disconnected, Recv returning zero incorrectly, didn't help me to understand.

Here I post the Network class: Network.h

    class Network
    {
        WSADATA wsaData;
        WORD wVersionRequested;
        int Port;
        unsigned int byteReceived, byteSent; 
        SOCKET listeningSocket, connectedSocket; 
        SOCKADDR_IN serverAddr, senderInfo, clientAddr;
        int caddrlen;

    char buff[DIM];
    string buffer;
    public:
        Network();
        ~Network();

    void Recv();
};


Network.c

void Network::Recv() {
    int n = recv(connectedSocket, buff, strlen(buff), 0);

    setByteReceived(n);
    buffer.assign(buff, n);
    cout << "Buffer is: " << buff << endl; 
    if (byteReceived == 0)
        cout << "\tConnection closed" << endl;
    else if (byteReceived > 0) {
        cout << "\tByte received: " << byteReceived << endl;
        cout << getBuffer() << endl;
    }
    else {
        myFormatMessage(WSAGetLastError());
    }
}


The behaviour in the end is the following: client and server are connected, the server returns 0 from recv(). I tried also to run both programs on the same machine. Thank you for your help.

Community
  • 1
  • 1
A. Wolf
  • 1,309
  • 17
  • 39
  • And you know that `recv()` received 0 exactly how? – Sam Varshavchik Sep 15 '16 at 17:13
  • I didn't say that :) I know only that recv() returns 0. I tried to use also wireshark to track the network traffic, but I've some problems with it. The behaviour seems different from Linux and I can't see the loopback interface even running the program as administrator. I don't know where the error could be. – A. Wolf Sep 15 '16 at 17:32

1 Answers1

3

You have:

void Network::Recv() {
    int n = recv(connectedSocket, buff, strlen(buff), 0);
    ...

If strlen(buff) returns 0 (because buff contains a null byte at index 0), you will be asking recv() to read 0 bytes, so it will return 0 bytes. You should be using sizeof(buff) instead of strlen(buff).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
jxh
  • 69,070
  • 8
  • 110
  • 193
  • buff is the buffer in which I save what I send from the client. I know that
    recv returns 0 when the sender closes the connection. Correct? I think that the client can't send 0 bytes..
    – A. Wolf Sep 15 '16 at 17:25
  • 2
    The third parameter to `recv` is how big your `buff` is so that `recv` knows when to not overflow the `buff`. But you pass in `0` to `recv`, so it doesn't read any bytes. – jxh Sep 15 '16 at 17:27
  • I wrote another program without the Network class, calling recv with the same parameters and it works. I mean the string is a C-like string in which before call recv there's nothing within it. (how can I use the code formatting in comment?
     doesn't work.. Thanks)
    – A. Wolf Sep 15 '16 at 17:37
  • *If `buff` is a zero length string...*. See markdown documentation for formatting. – jxh Sep 15 '16 at 17:41
  • 2
    `strlen(buff)` returns 0 if `buff` begins with a null byte. *Never* use `strlen()` to get the size of an input buffer. You need to tell `recv()` the actual size of `buff`. And since `buff` is a static array, you can use `sizeof(buff)` for that. – Remy Lebeau Sep 15 '16 at 18:01
  • @user2993413 welcome to the wonderful world of programming where you are going to find that faulty code working in one circumstance does not mean it will work in others. Odds are good that in your "working" case there is something in `buff` that `strlen` counts. Since buff is only initialized in `setBuff`, if you read before writing, you wander into undefined behaviour when you call `strlen`. Anything can happen. – user4581301 Sep 15 '16 at 18:01
  • Thank you @RemyLebeau, I didn't know about that. Could you put it as answer please to close the answer? Thanks again. – A. Wolf Sep 15 '16 at 18:26
  • @user4581301 even if I spent 3 years in this wonderful world I'm not used to this situation hahahah. – A. Wolf Sep 15 '16 at 18:27
  • @user2993413: the answer above is adequate, you should accept it instead. – Remy Lebeau Sep 15 '16 at 18:40