I am currently trying to create an application to send messages from a server to a client after initiating the connection by sending filters from the client to the server (like a subscrition). The entire application is done but I found out that the messages I send contain special caracters and dont have the size they are supposed to have. Here is an example with the filters (which are 3 letter words) that the server receives:
Client connected!
Bytes received: 3
REceived Filters:ATL����������������������
Although it says that 3 bytes were received, it prints 25 caracters.
Here is the server side part of the code I use to receive the filters:
// Receiving and sending data on server socket
int iSendResult;
// buffer for received msg
char recvbuf[3];
int recvbuflen = 3;
int compteurSend = 1;
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
{
printf("\nBytes received: %d\n", iResult);
printf("REceived Filters:");
std::cout << recvbuf << "\n" << std::endl;
}
...... rest of the code to send back data ......
And here is the client side part of the code I use to send te filters:
// Sending and receiving data
// buffer for sending filters
const char* sendbuf = "ATL";
int sendbuflen = strlen(sendbuf);
// buffer for receiving
char recvbuf[4000];
int recvbuflen = sizeof(recvbuf);
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, sendbuflen, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
std::cout << "Filters Sent: " << "'" << sendbuf << "'" << " containing " << iResult << " bytes\n\n";
While the output of the cout on the client part is correct, stating " Filters Sent: 'ATL' containing 3 bytes ", I can only understand that the issue comes from the server side and the alocation of the buffer size. Did I miss anything or did I mess up on the use of sizeof and strlen.
CodePudding user response:
std::cout << recvbuf
is treating recvbuf
as a null-terminated char*
string, but there is no null terminator being sent by the client, and no null terminator being inserted by the server after the data received. So, operator<<
ends up reading past the valid data, which is why you are seeing extra garbage being printed.
So, you can either:
- update the client to send the null terminator (just make sure the server's
recvbuf
is large enough to receive it):
const char* sendbuf = "ATL";
int sendbuflen = strlen(sendbuf) 1; // <-- here
- add a null terminator artificially on the server side:
char recvbuf[4];
do {
iResult = recv(ClientSocket, recvbuf, sizeof(recvbuf)-1, 0);
if (iResult > 0)
{
recvbuf[iResult] = '\0'; // <-- here
printf("\nBytes received: %d\n", iResult);
printf("Received Filters:");
std::cout << recvbuf << "\n" << std::endl;
}
- since
recv()
tells you how many bytes are actually received, simply useostream::write()
instead ofoperator<<
, eg:
std::cout.write(recvbuf, iResult);
std::cout << "\n" << std::endl;