Winsock 2 recv() hangs after recv some data. Help on send/recv using WinSock

Jan 13, 2012 at 9:29am
Hi all,

i have created a basic console application for WinSock2 Client. Here is the code i use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#define WIN32_LEAN_AND_MEAN

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

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main() {

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

    SOCKET ConnectSocket = INVALID_SOCKET;
    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);

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
            
            //I also print here the recvbuff just to read responce

        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed: %d\n", WSAGetLastError());

    } while( iResult > 0 );

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

    return 0;
}


My problem is that i recv some answer which is the login confirmation. Then a data flow should start but it happens nothing. App just hangs so for internally.

Is there something i miss here?

Answers will be highly appreciated !
Thankx
Jan 13, 2012 at 3:10pm
I don't think you understand how recv() works for data larger than your specified buffer. If you have already retrieved all the data the server has for you then recv() will block until more is available (probably why your app "hangs").

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  while((iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0)) != 0) // continue till disconnected
  {
    if(iResult == -1)
    {
      if(WSAGetLastError() == WSAEMSGSIZE) // server has more data to send than the buffer can get in one call
      {
        continue; // iterate again to get more data
      } else {
        // some other error
        printf("recv failed: %d\n", WSAGetLastError());
      }
    } else {
      // if iResult is numeric then it has retrieved what it needed and no more is currently available so if we call recv() again it will block.
      printf("Bytes received: %d\n", iResult);
      break;
    }
  }
  if(!iResult)  printf("Connection closed\n");
Jan 15, 2012 at 9:54am
Wow yes thanks i really miss that. Many thanks for your help it works now as needed. You saved me!
Topic archived. No new replies allowed.