Socket error in C using read and write functions - c++

I am attempting to read and write to a socket using linux networking programming in C. I make successful calls to "write" and "read" in the client and server programs respectively.
The part I am having difficulty understanding is that on my client program, I loop and call the write 5 different times, on the server, I loop and call the read 5 different times.
This is the expected output:
MSG: I got your message MSG: I got your message MSG: I got your message MSG: I got your message MSG: I got your message
This is the actual output:
MSG: I got your messageI got your messageMSG: I got your messageI got your messageMSG: I got your messageMSG: MSG:
As you can see the expected output and the actual output are different. It looks like the client is able to call "write" twice before it is actually sent.
This is what I have for the client code
for(int i=0;i<5;i++)
{
int n = write(ssocket.socketFileDescriptor,"I got your message",18);
cout<<n<<" number of bytes written."<<endl;
if (n < 0) socketError("ERROR writing to socket");
}
This is the server code:
void* run(void* arg)
{
ServerSocket* ss = (ServerSocket*)arg;
//while(true)
for(int i=0;i<5;i++)
{
char buffer[256];
bzero(buffer,256);
int n = read(ss->newsockfd,buffer,256);
printf("MSG: %s",buffer);
}
close(ss->newsockfd);
}
This is an addition to the question below which is out of date at this point.
Am I missing a call to flush or something?
Simulate Java's Thread class in C++

Your client and server are just not coordinated. The client writes the message 5 times as quickly as it can, and the server reads five times as quickly as it can. In your example output, evidently on your first call to read() the client has sent the message twice, and on the second call to read() it's sent it a further two times. You read() up to 256 characters, and each time you call it, it will just attempt to read anything that's currently in the buffer. If the client has send multiple messages by that time, read() will just grab everything.
You typically need some type of synchronization, e.g. after you send one message, your client waits for the server to send "OK" or something similar before it sends the second message. Short of that, you can use some kind of end-of-message marker (such as a newline) so the server can differentiate them, if you have a very simple communication format.

Related

Unix socket hangs on recv, until I place/remove a breakpoint anywhere

[TL;DR version: the code below hangs indefinitely on the second recv() call both in Release and Debug mode. In Debug, if I place or remove a breakpoint anywhere in the code, it makes the execution continue and everything behaves normally]
I'm coding a simple client-server communication using UNIX sockets. The server is in C++ while the client is in python. The connection (TCP socket on localhost) gets established no problem, but when it comes to receiving data on the server side, it hangs on the recv function. Here is the code where the problem happens:
bool server::readBody(int csock) // csock is the socket filedescriptor
{
int bytecount;
// protobuf-related variables
google::protobuf::uint32 siz;
kinMsg::request message;
// if the code is working, client will send false
// I initialize at true to be sure that the message is actually read
message.set_endconnection(true);
// First, read 4-characters header for extracting data size
char buffer_hdr[5];
if((bytecount = recv(csock, buffer_hdr, 4, MSG_WAITALL))== -1)
::std::cerr << "Error receiving data "<< ::std::endl;
buffer_hdr[4] = '\0';
siz = atoi(buffer_hdr);
// Second, read the data. The code hangs here !!
char buffer [siz];
if((bytecount = recv(csock, (void *)buffer, siz, MSG_WAITALL))== -1)
::std::cerr << "Error receiving data " << errno << ::std::endl;
//Finally, process the protobuf message
google::protobuf::io::ArrayInputStream ais(buffer,siz);
google::protobuf::io::CodedInputStream coded_input(&ais);
google::protobuf::io::CodedInputStream::Limit msgLimit = coded_input.PushLimit(siz);
message.ParseFromCodedStream(&coded_input);
coded_input.PopLimit(msgLimit);
if (message.has_endconnection())
return !message.endconnection();
return false;
}
As can be seen in the code, the protocol is such that the client will first send the number of bytes in the message in a 4-character array, followed by the protobuf message itself. The first recv call works well and does not hang. Then, the code hangs on the second recv call, which should be recovering the body of the message.
Now, for the interesting part. When run in Release mode, the code hangs indefinitely and I have to kill either the client or the server. It does not matter whether I run it from my IDE (qtcreator), or from the CLI after a clean build (using cmake/g++).
When I run the code in Debug mode, it also hangs at the same recv() call. Then, if I place or remove a breakpoint ANYWHERE in the code (before or after that line of code), it starts again and works perfectly : the server receives the data, and reads the correct message.endconnection() value before returning out of the readBody function. The breakpoint that I have to place to trigger this behavior is not necessarily trigerred. Since the readBody() function is in a loop (my C++ server waits for requests from the python client), at the next iteration, the same behavior happens again, and I have to place or remove a breakpoint anywhere in the code, which is not necessarily triggered, in order to go past that recv() call. The loop looks like this:
bool connection = true;
// server waiting for client connection
if (!waitForConnection(connectionID)) std::cerr << "Error accepting connection" << ::std::endl;
// main loop
while(connection)
{
if((bytecount = recv(connectionID, buffer, 4, MSG_PEEK))== -1)
{
::std::cerr << "Error receiving data "<< ::std::endl;
}
else if (bytecount == 0)
break;
try
{
if(readBody(connectionID))
{
sendResponse(connectionID);
}
// if client is requesting disconnection, break the while(true)
else
{
std::cout << "Disconnection requested by client. Exiting ..." << std::endl;
connection = false;
}
}
catch(...)
{
std::cerr << "Erro receiving message from client" << std::endl;
}
}
Finally, as you can see, when the program returns from readBody(), it sends back another message to the client, which processes it and prints in the standard output (python code working, not shown because the question is already long enough). From this last behavior, I can conclude that the protocol and client code are OK. I tried to put sleep instructions at many points to see whether it was a timing problem, but it did not change anything.
I searched all over Google and SO for a similar problem, but did not find anything. Help would be much appreciated !
The solution is to not use any flags. Call recv with 0 for the flags or just use read instead of recv.
You are requesting the socket for data that is not there. The recv expects 10 bytes, but the client only sent 6. The MSG_WAITALL states clearly that the call should block until 10 bytes are available in the stream.
If you dont use any flags, the call will succeed with a bytecount at 6, which is the exact same effect than with MSG_DONTWAIT, without the potential side effects of non-blocking calls.
I did the test on the github project, it works.
The solution is to replace MSG_WAITALL by MSG_DONTWAIT in the recv() calls. It now works fine. To summarize, it makes the recv() calls non blocking, which makes the whole code work fine.
However, this still raises many questions, the first of which being: why was it working with this weird breakpoint changing thing ?
If the socket was blocking in the first place, one could assume that it is because there is no data on the socket. Let's assume both situations here :
There is no data on the socket, which is the reason why the blocking recv() call was not working. Changing it to a non blocking recv() call would then, in the same situation, trigger an error. If not, the protobuf deserialization would afterwards fail trying to deserialize from an empty buffer. But it does not ...
There is data on the socket. Then, why on earth would it block in the first place ?
Obviously there is something that I don't get about sockets in C, and I'd be very happy if somebody has an explanation for this behavior !

How would one avoid race conditions from multiple threads of a server sending data to a client? C++

I was following a tutorial on youtube on building a chat program using winsock and c++. Unfortunately the tutorial never bothered to consider race conditions, and this causes many problems.
The tutorial had us open a new thread every time a new client connected to the chat server, which would handle receiving and processing data from that individual client.
void Server::ClientHandlerThread(int ID) //ID = the index in the SOCKET Connections array
{
Packet PacketType;
while (true)
{
if (!serverptr->GetPacketType(ID, PacketType)) //Get packet type
break; //If there is an issue getting the packet type, exit this loop
if (!serverptr->ProcessPacket(ID, PacketType)) //Process packet (packet type)
break; //If there is an issue processing the packet, exit this loop
}
std::cout << "Lost connection to client ID: " << ID << std::endl;
}
When the client sends a message, the thread will process it and send it by first sending packet type, then sending the size of the message/packet, and finally sending the message.
bool Server::SendString(int ID, std::string & _string)
{
if (!SendPacketType(ID, P_ChatMessage))
return false;
int bufferlength = _string.size();
if (!SendInt(ID, bufferlength))
return false;
int RetnCheck = send(Connections[ID], _string.c_str(), bufferlength, NULL); //Send string buffer
if (RetnCheck == SOCKET_ERROR)
return false;
return true;
}
The issue arises when two threads (Two separate clients) are synchronously trying to send a message at the same time to the same ID. (The same third client). One thread may send to the client the int packet type, so the client is now prepared to receive an int, but then the second thread sends a string. (Because the thread assumes the client is waiting for that). The client is unable to process correctly and results in the program being unusable.
How would I solve this issue?
One solution I had:
Rather than allow each thread to execute server commands on their own, they would set an input value. The main server thread would loop through all the input values from each thread and then execute the commands one by one.
However I am unsure this won't have problems of its own... If a client sends multiple messages in the time frame of a single server loop, only one of the messages will send (since the new message would over-write the previous message). Of course there are ways around this, such as arrays of input or faster loops, but it still poses a problem.
Another issue that I thought of was that a client with a lower ID would always end up having their message sent first each loop. This isn't that big of a deal but if there was a situation, say, a trivia game, where two clients entered the correct answer in the same loop then the client with the lower ID would end up saying the answer "first" every time.
Thanks in advance.
If all I/O is being handled through a central server, a simple (but certainly not elegant) solution is to create a barrier around the I/O mechanisms to each client. In the simplest case this can just be a mutex. Associate that barrier with each client and anytime someone wants to send that client something (a complete message), lock the barrier. Unlock it when the complete message is handled. That way only one client can actually send something to another client at a time. In C++11, see std::mutex.

Wait for incoming data in a C++ client socket application

Through a tutorial I was able to built a C++ client application that connects to a server and is able to send and receive data.
Currently the application ends after it receives a string from the server. What I want to do is to let the client keep listening for incoming data.
Currently a part of my code looks like this:
string tcp_client::receive(int size=512)
{
char buffer[size];
string reply;
//Receive a reply from the server
if( recv(sock , buffer , sizeof(buffer) , 0) < 0)
{
puts("recv failed");
}
reply = buffer;
return reply;
}
int main(int argc , char *argv[])
{
tcp_client c;
string host;
cout<<"Enter hostname : ";
cin>>host;
c.conn(host , 4004);
//send some data
c.send_data("TEST STRING \n\r\n");
//receive and echo reply
// (want to keep listening here for data)
cout<<c.receive(1024);
//done
return 0;
}
I don't want the client to end but I want it to keep listening for data. I'm thinking about adding this code:
while(buffer = c.receive(1024))
{
// do something with buffer ... switch/case construction
// After that, start listening again
}
First of all I'm not sure if this works. But second, I'm also not sure if it's smart to put in a never ending while loop in there (never ending, until I terminate the application of course).
Can I simply put in a while loop like that? Or are there other. better methods to make a client application keep listening for data?
You should check if you at a certain point you receive 0 bytes , which means that the other end has closed the connection and is not going to send anymore. That means that you can close your socket too and close the application.
Under normal condition , when the server is also running, receive is a blocking call, it just hangs there until there is something received.
Now if the server closes the connection you really must exit the endless loop or you will continuously call receive on a socket that is closed which will return immediately taking a lot of load on your cpu.
All programs should generally take care of the error conditions or unexpected behavior can occur.
Yes you should put receive in a loop. But you should know that the receive call will block your program until it finds any data. That means if you are working with a GUI, your GUI will halt until the receive will unblock the program. For console application its ok..

C++ Server - Client Message Sync

I writing a small program that can Send File from Client -> Server (Send) and Server -> Client(Request).
Well done this part but the problems comes when:
1. I found the File on Server, How can I execute a cin on the client side?
2. How can I force my messages between Server and Client to be synced? I mean I dont want the Server to move to next step or freeze on the receive.
For Example(No Threading applied in this porblem):-
Server: Waiting a Message from Client.
Client: Send the Message.
Client: Waiting a Message from Client.
Server: Send the Message.
.....etc.
In a rare times the messages arrive on order but 99.999% of the time they don't and the program on two sides freeze.
The problem with the inorder messages was a thread on the client side who kept reading the inc replies without allowing the actual functions to see them.
However, about point 1.
I am trying in this code:
1. No shared resources so i am trying to define everything inside this function (part of it where the problem happening)
2. I was trying to pass this function to a thread so the server can accept more clients.
3. send & receive nothing special about them just a normal send/recv calls.
3. Question: if SendMyMessage & ReceiveMyMessage is going to be used by different threads, should I pass the socket to them with the message?
void ExecuteRequest(void * x)
{
RequestInfo * req = (RequestInfo *) x;
// 1st Message Direction get or put
fstream myFile;
myFile.open(req->_fName);
char tmp;
string _MSG= "";
string cFile = "*";
if(req->_fDir.compare("put") == 0)
{
if(myFile.is_open())
{
SendMyMessage("*F*");
cFile = ReceiveMyMessage();
// I want here to ask the client what to do after he found the that file exist on the server,
// I want the client to to get a message "*F*", then a cin command appear to him
// then the client enter a char
// then a message sent back to the server
// then the server continue executing the code
//More code
}
Client side:
{
cout <<"Waiting Message" <<endl;
temps = ReceiveMessage();
if(temps.compare("*F*") == 0)
{
cout <<"File found on Server want to:\n(1)Replace it.\n(2)Append to it." <<endl;
cin>>temps;
SendMyMessage(temps);
}}
I am using visual studio 2013
Windowx 7
thread am using: _beginthread (I removed all threads)
Regards,
On linux, there is a system call "select" using which the server can wait on the open sockets. As soon as there is an activity, like client wrote something, the server wakes up on that sockets and processes the data.
You are on windows platform. So :
http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx

flush buffer in a boost::asio program

Basically I am writing a simple program using the boost socket library... I have two programs a client and a server. the server waits for a connection from the client and when it finds one the client sends the server a message and the server prints out, this works the first time the client queries the server but after a while an strange pattern begins lets say our server was running and I used the client program two times by executing:
./client localhost name message
./client localhost name test
the output 0f the server would first be:
name: message
however next it would display
name: testage
I don't know why this is happening but I know it must be the server, because the the clients each send a packet independently the server just prints it out... I'm thinking that this has something to do with the socket buffer not being flushed or something of that nature...
anyway heres the sourcecode:
client.cpp
http://pastebin.com/hWpLNqnW
server.cpp
http://pastebin.com/Q4esYwdc
The read_some call in the server returns the number of bytes read. You should use that value and use it to null terminate the buffer. Something along these lines:
int len = connection.read_some(boost::asio::buffer(buf), error);
buf[len] = '\0';
In the first message, the buffer may have been initialized with zeros. The next time, though, it would contain the same contents as the previous iteration. Note that the strcpy(buf,""); call only ends up setting the first byte of buf to zero.