user14089077
user14089077

Reputation:

recv() returns strange buffer C++

I know C++ for quite long, but started using it for my purposes some what a year and a half ago. I started learning network programming on C++ and the first networking project is "File Transfering between hosts over TCP/IP" which sounds kind easy but I am stuck with sending data.

I am trying to send small buffer less than 4KB, so buffer[4096] works fine for me, but I am planning to expand this. WSAStartup(), socket(), bind(), listen(), accept() functions work fine and values for them are initialised for both Server and Client, but I am dealing with other problems, maybe recv(), send() etc. I still couldn't find the source of the problem.

Also it would be a ton helpful if somebody give me an example of transfering files over TCP/IP, but not in one packet, I want the file to be chunked and sent in parts or as it's called "ring model", but I couldn't find a working model;

P.S. This is first time I am asking here, pls give feedback about how well all of this is written, so that I could write more informative for community help, thanks)

Server

char* buffer = new char[4096];
ZeroMemory(buffer, sizeof(buffer));
ofstream file("a.txt", ios::binary);
int err = recv(conn, buffer, sizeof(buffer), 0);
file << buffer;
file.close();
if (err == 0)
{
    printf("Client diconnected...\n");
}

printf("Quitting...\n");
delete[] buffer;

Client

ifstream file("a.txt", ios::binary);
file.seekg(0, ios::end);
int size = file.tellg();
file.seekg(0, ios::beg);
char* buffer = new char[size];
file.read(buffer, size);
file.close();

int err = send(client, buffer, size, 0);
if (err == 0)
{
    printf("Disconnecting...\n");
}

printf("Quitting...\n");
delete[] buffer;

"a.txt" file on Client side is 45 bytes in here are 45 * 'a'

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

And this is what I get on Server side, file size is 14 bytes

aaaaaaaa ’pÈ/

Upvotes: 0

Views: 534

Answers (4)

keithmo
keithmo

Reputation: 4943

Two additional points:

  • TCP is a streaming protocol (not "message based"), so there's no guarantee that a single recv() will get everything sent in a single send().

  • The server line file << buffer; assumes buffer is zero terminated.

Upvotes: 1

MSalters
MSalters

Reputation: 179779

In C++, sizeof(buffer) is the size of the pointer type.

You may want to read up on more modern (as in after 1998) C++. We have std::vector nowadays, and that has a convenient size method. It would return 4096 for your buffer. Also, vector handles new[] and delete[] for you.

The fact that you get 8 "a"'s suggests that you built for x64. The remaining bytes are garbage; you should check how many bytes recv actually wrote to buffer. You cannot assume that you got all the bytes you asked for (whether that's 8 or 4096).

Upvotes: 2

Ifeanyi Nmoye
Ifeanyi Nmoye

Reputation: 72

I believe that sizeof(buffer) in this line -->

int err = recv(conn, buffer, sizeof(buffer), 0);

will return sizeof(char*) which is 4 bytes in a 32 bit program or 8 bytes in a 64 bits program instead of 4096 because it is not a static array as in you did not declare it as char buffer[4096]. So, either declare it as char buffer[4096] or convert the above code to

int err = recv(conn, buffer, 4096, 0);

Upvotes: 1

MLeblanc
MLeblanc

Reputation: 1884

MSDN state that :

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.

https://learn.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-recv

test if you actually read 45 bytes and check if there's an error (WSAGetLastError function)

Upvotes: 0

Related Questions