Winsock Functions


recv Function

The recv function receives data from a connected socket or a bound connectionless socket.

Syntax

C++
int recv(
  __in   SOCKET s,
  __out  char *buf,
  __in   int len,
  __in   int flags
);

Parameters

s [in]

The descriptor that identifies a connected socket.

buf [out]

A pointer to the buffer to receive the incoming data.

len [in]

The length, in bytes, of the buffer pointed to by the buf parameter.

flags [in]

A set of flags that influences the behavior of this function. See remarks below. See the Remarks section for details on the possible value for this parameter.

Return Value

If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.

Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.

Error codeMeaning
WSANOTINITIALISED

A successful WSAStartup call must occur before using this function.

WSAENETDOWN

The network subsystem has failed.

WSAEFAULT

The buf parameter is not completely contained in a valid part of the user address space.

WSAENOTCONN

The socket is not connected.

WSAEINTR

The (blocking) call was canceled through WSACancelBlockingCall.

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAENETRESET

For a connection-oriented socket, this error indicates that the connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. For a datagram socket, this error indicates that the time to live has expired.

WSAENOTSOCK

The descriptor is not a socket.

WSAEOPNOTSUPP

MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only send operations.

WSAESHUTDOWN

The socket has been shut down; it is not possible to receive on a socket after shutdown has been invoked with how set to SD_RECEIVE or SD_BOTH.

WSAEWOULDBLOCK

The socket is marked as nonblocking and the receive operation would block.

WSAEMSGSIZE

The message was too large to fit into the specified buffer and was truncated.

WSAEINVAL

The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled or (for byte stream sockets only) len was zero or negative.

WSAECONNABORTED

The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.

WSAETIMEDOUT

The connection has been dropped because of a network failure or because the peer system failed to respond.

WSAECONNRESET

The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is no longer usable. On a UPD-datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.

 

Remarks

The recv function is used to read incoming data on connection-oriented sockets, or connectionless sockets. When using a connection-oriented protocol, the sockets must be connected before calling recv. When using a connectionless protocol, the sockets must be bound before calling recv.

The local address of the socket must be known. For server applications, use an explicit bind function or an implicit accept or WSAAccept function. Explicit binding is discouraged for client applications. For client applications, the socket can become bound implicitly to a local address using connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.

For connected or connectionless sockets, the recv function restricts the addresses from which received messages are accepted. The function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded.

For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available—up to the size of the buffer specified. If the socket has been configured for in-line reception of OOB data (socket option SO_OOBINLINE) and OOB data is yet unread, only OOB data will be returned. The application can use the ioctlsocket or WSAIoctlSIOCATMARK command to determine whether any more OOB data remains to be read.

For connectionless sockets (type SOCK_DGRAM or other message-oriented sockets), data is extracted from the first enqueued datagram (message) from the destination address specified by the connect function.

If the datagram or message is larger than the buffer specified, the buffer is filled with the first part of the datagram, and recv generates the error WSAEMSGSIZE. For unreliable protocols (for example, UDP) the excess data is lost; for reliable protocols, the data is retained by the service provider until it is successfully read by calling recv with a large enough buffer.

If no incoming data is available at the socket, the recv call blocks and waits for data to arrive according to the blocking rules defined for WSARecv with the MSG_PARTIAL flag not set unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to WSAEWOULDBLOCK. The select, WSAAsyncSelect, or WSAEventSelect functions can be used to determine when more data arrives.

If the socket is connection oriented and the remote side has shut down the connection gracefully, and all data has been received, a recv will complete immediately with zero bytes received. If the connection has been reset, a recv will fail with the error WSAECONNRESET.

Note  When issuing a blocking Winsock call, such as send, recv, select, accept, or connect function calls, Winsock may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread, and thereby create unspecified results. Do not issue blocking Winsock function calls without being certain that the current thread is not waiting inside another blocking Winsock function call; doing so results in unpredictable behavior.

The flags parameter can be used to influence the behavior of the function invocation beyond the options specified for the associated socket. The semantics of this function are determined by the socket options and the flags parameter. The possible value of flags parameter is constructed by using the bitwise OR operator with any of the following values.

ValueMeaning
MSG_PEEKPeeks at the incoming data. The data is copied into the buffer, but is not removed from the input queue. The function subsequently returns the amount of data that can be read in a single call to the recv (or recvfrom) function, which may not be the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the recv (or recvfrom) function is limited to the data size written in the send or sendto function call.
MSG_OOBProcesses Out Of Band (OOB) data.
MSG_WAITALLThe receive request will complete only when one of the following events occurs:

  • The buffer supplied by the caller is completely full.
  • The connection has been closed.
  • The request has been canceled or an error occurred.
Note that if the underlying transport does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP. Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP. This flag is not supported on datagram sockets or message-oriented CO sockets.

 

Example Code

The following code example shows the use of the recv function.

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main() {

    //----------------------
    // Declare and initialize variables.
    WSADATA wsaData;
    int iResult;

    SOCKET ConnectSocket;
    struct sockaddr_in clientService; 

    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
  
    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
      printf("WSAStartup failed: %d\n", iResult);
      return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( 27015 );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if ( iResult == SOCKET_ERROR) {
        closesocket (ConnectSocket);
        printf("Unable to connect to server: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}

Example Code

For more information, and another example of the recv function, see Getting Started With Winsock.

Requirements

Minimum supported clientWindows 2000 Professional
Minimum supported serverWindows 2000 Server
HeaderWinsock2.h
LibraryWs2_32.lib
DLLWs2_32.dll

See Also

Winsock Reference
Winsock Functions
recvfrom
select
send
socket
WSAAsyncSelect
WSARecv
WSARecvEx

Send comments about this topic to Microsoft

Build date: 11/12/2009

Tags :


Community Content

geeky
calling recv will return as much data as is currently available...
Maybe the sentence:
"For connection-oriented sockets (type SOCK_STREAM for example), calling  recv will return as much data as is currently available—up to the size of the buffer specified."
Should be highlighted in some way. An "attention!"-box or something like that ;D
Currently many people think that calling recv() will always fill up the complete buffer ("len" ;D)
Even if you point them to the msdn and quote that phrase in boards, they still do not seem to get it (or do not want to ;D)
Tags :

ilean_
recv..
there should be some sample show how to deal with the unicode recv() in c++ so as clr library do
Tags : suggestion

ilean_
recv

It's a low-level function byte based. At this point there is no sense any codification (neither ASCII nor UNICODE).

Perhaps your error comes on the char* parameter. It will be clearer if this was a BYTE*, but keep in mind that it is de same.

Tags :

Medinoc
recv() should use a generic pointer, like fread() and _read()
The problem is, it should be void*, and not char* not BYTE*.

I fail to understand why it is char* in the first place. It's not the case in POSIX sockets...


Tags : char recv void

Jim Blaney
Any explanation of why recv() might have 12 second delay the first time after a socket open/write?
I'd like to see mentioned any overhead/penalty that might be incurred on initial recv calls -- I currently am seeing a very reproducible 12-14 second delay on the first call to recv (immediately after a sockent open, followed by a write). This is using Winsock 1.1 compatibility, which I'm suspecting might be an issue on Windows 2003 Server 64.
Tags :

EziaSolsky
It seems that MSG_WAITALL isn't supported in WinXP and earlier.
It seems that MSG_WAITALL isn't supported in WinXP and earlier.
I wrote a programme using TCP and blocking in WinXP. Called recv(...MSG_WAITALL), and it immediatly returned SOCKET_ERROR. WSAGetLastError() returned WSAEOPNOTSUPP.

MattTheWaz
Bytes sent != bytes recv
I'm writing both ends of a SOCKET connection.

On the sending side I invoke send() to send a 24 byte packet and successfully get a return value of 24 bytes
On the receiving side I invoke recv() to recv the same 24 bytes but only get 15 bytes.

Basically I'm casting an object as a character array, copying it into a 24 byte character array and sending it. The receiving end should take the 24 byte character array it gets, allocate memory for an object of the same type that was sent and copy the data from the character array into it.

I don't seem to be suffering any data loss when this happens so I think it's just lopping off trailing 0s... yet now I'm pulling the start of my next packet in with it, destroying both packets.

Sunny158
second call to recv crashes
I have very similar code for the client as described above but my code crashes on the second call to recv. I think there is no data on the socket when recv is called for second time but I am not sure how to handle it.
Tags : recv crash

Sanjay Umap
recv - recv hangs for 50-55 seconds when connection is been closed from sender side
I have a problem,

When I try receiving a buffer and at the same time sender closes connection, the recv() hangs for 50-55 seconds. How do I reduce this receive timeout?


Tags :

Page view tracker