WinSock 2.2 send() function always returns me all the bytes I want it to send! I am connecting to google.com on port 80 and sending random t
letters for data. I even tried to send as many as 1GB of t
's. It still returns with all bytes sent. I was expecting it to return back with me with how many bytes it could fit in a packet and the rest would be handled by the while loop in the implementation, but it never enters inside the while loop as a result!
I am using TCP/IPv4 sockets. I know my internet is not lighting fast to send 1GB faster than I can blink.
This code is shown for most important chunks. For example a wrapper for the C-string send call is omitted that calls the send I shown.
Calling test code
//prepare the long data string
int buffSize = 1 * 1000 * 1000 * 1000;
char *buff = new char[buffSize];
memset(buff, 't', buffSize);
buff[buffSize - 3] = '\n';
buff[buffSize - 2] = '\n';
buff[buffSize - 1] = '\0';
//send thee data
int bytesSent = socket->send(buff);
//verify all thee data is sent
CHECK(bytesSent == strlen(buff));
Send implementatian
int mySocket::send(const void *data, int length)
{
int bytesSent = ::send(socketDescriptor, (char*)data, length, 0);
if (bytesSent == SOCKET_ERROR) return -1;
while(bytesSent < length)
{
int sent = ::send(socketDescriptor, (char*)data + bytesSent, length - bytesSent, 0);
if (sent == SOCKET_ERROR) return bytesSent;
bytesSent += sent;
}
return bytesSent;
}
EDIT 1
Since it started to confuse people here is the wrapper
Send wrapper
int mySocket::send(const char * data_string)
{
return send(dataString, strlen(data_string));
}
EDIT 2
here is a full working example you can debug. it produces the same result, it just instantly reports all bytes as sent.
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
class mySocket
{
public:
mySocket(SOCKET sockeDesc)
{
socketDescriptor = sockeDesc;
}
int mySocket::send(const void *data, int length)
{
int bytesSent = ::send(socketDescriptor, (char*)data, length, 0);
if (bytesSent == SOCKET_ERROR) return -1;
while (bytesSent < length)
{
int sent = ::send(socketDescriptor, (char*)data + bytesSent, length - bytesSent, 0);
if (sent == SOCKET_ERROR) return bytesSent;
bytesSent += sent;
}
return bytesSent;
}
int mySocket::send(const char * data_string)
{
return send(data_string, strlen(data_string));
}
private:
SOCKET socketDescriptor;
};
int main()
{
WSAData wsd;
if (WSAStartup(MAKEWORD(2, 2), &wsd) || wsd.wVersion != MAKEWORD(2, 2))
{
WSACleanup();
return 1;
}
//create ze socket
SOCKET socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
//look up socket info
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
addrinfo *res;
int errCode = getaddrinfo("google.com", "80", &hints, &res);
if (errCode) return 1;
//connect ze socket
int connectStatusCode = ::connect(socketDescriptor, res->ai_addr, res->ai_addrlen);
if (connectStatusCode == SOCKET_ERROR) return 1;
//create zeeeee socket!
mySocket *socket = new mySocket(socketDescriptor);
//prepare ze long data string
int buffSize = 1 * 1000 * 1000 * 1000;
char *buff = new char[buffSize];
memset(buff, 't', buffSize);
buff[buffSize - 3] = '\n';
buff[buffSize - 2] = '\n';
buff[buffSize - 1] = '\0';
//send ze data
int bytesSent = socket->send(buff);
//verify all ze data is sent
bool success = (bytesSent == strlen(buff));
printf("requested bytes = %i\nsent bytes = \t %i", strlen(buff), bytesSent);
printf("\n\nsuccess = %s", success ? "true" : "false");
closesocket(socketDescriptor);
delete socket;
freeaddrinfo(res);
WSACleanup();
getchar();
return 0;
}
EDIT 3
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
Remarks
...
The successful completion of a send function does not indicate that the data was successfully delivered and received to the recipient. This function only indicates the data was successfully sent.
but @Karsten Koop, pointed to similar question on related behaviour: What is the size of a socket send buffer in Windows? i badly understand what's writtent there. but what i got is it says the function simply writes to a buffer and returns the bytes "sent". but this not only means it doesn't guarantee that the recepient received the data(which microsoft states) BUT it means it isn't actually sent at all... just in a buffer. am i missing something here or is microsoft misleading about its behaviour?