i have two projects: one is a client and one is a server.
lets say the server as to send 2 messages one after the other to the client.
the client code is like this:
while(1)
{
recv(acceptedStr, socket);
printf("%s\n, acceptedStr);
*other code lines*
}
while the server code is like this:
while(1)
{
send(socket, "First String");
send(socket, "Second String");
*other code lines*
}
if there is no TIME_OUT for the second send, will the recv of the client get "Second String"? or does he have to make sure that he is in a recv before the server send?
No, the receiving end does not need to have an recv active for the send to work.
Once a connection is established, the data is buffered by the OS network stack. And recv will succeed once data has arrived and send will succeed if the data was delivered to the network stack of the receiver.
Answer to your question
Yes, That is enough and your code will work. But if you want to extend it more, or if the server and the client need to be at sync at all times, do continue reading.
Sync of server and client
Do read this if you want synchronous operations of server and client.
I have previously worked with send and recv and one thing that I would suggest you is that you always alternate the recv and send in complementary ways. As an example
Server:
send()
recv()
send()
.
.
.
Client:
recv()
send()
recv()
.
.
.
This usually gets tiring to keep track of. (I think the return send from a entity on recv is called ack).
But, at some point you would like to turn the flow of events. For this, you can just send and recv some random data.
I had previously written a wrapper around send and recv for a project of mine. Feel free to check it out: https://github.com/ArenaGrenade/Simple-FTP-Server/blob/main/utils.cpp. (Its pretty well documented, so even if you did not understand my explanation you would understand the one in code.)
Let me know if you understood by marking mine as an answer. Happy to help! If you have doubts just comment below. :)
The client does receive the Second String, but it does not work as you think it should.
I created the client and server through the two official samples:Complete Winsock Client Code and Complete Winsock Server Code
I modified the sample so that the server only sends data and the client only receives data.
When I try to send data twice in a row, the client will receive the following content:
You can see that the client does receive Second String, but because you keep sending these two data, it will cause problems in the picture.
Because the data is being sent continuously, the client will also receive the data sent multiple times at one time, and save them to the same buffer, although only part of it is displayed (because it is truncated by'\0'), but It can be seen from the size of the buffer that the data sent multiple times is received at one time.And the content received later will be unpredictable
Related
in my code i call SSL_do_handshake() function.
Everything works fine if the server gets the "right" messages.
BUT, for security issues I tried sending a dummy message. just "hello" to the right port and the right ip address.
in this case, SSL_do_handshake() gets stuck forever.
I want the function to return in that case, so that my server will not get stuck.
What are the options ?
I read about setting bio to non-blocking..
I added to my code :
BIO_set_nbio(bio, 1); before the connection is established..
but it didn't do thew work...
What can I do ?
BIO_set_nbio sets only the flag, that the bio should be considered non-blocking. You have to actually make the socket itself non-blocking.
I have a question about communication between a client and a server. I would like to send data over a TCP unix socket (I know how to do this), and I don't know what is the best practises to test if the message sent is ready to be read entirely (not block per block).
Thus, I'm thinking of this
The client send the data printf(3) formatted, the message is written in a string and sent.
The server receive the message, but how to be sure the message if full ? Do I need to loop until the message is complete ?
So my idea is to use a code (or checksum maybe ?) that will be prepended and appended to the message like this :
[verification code] my_long_data_formatted [verification code]
And then, the server tries to read the data until the second verification code is read and succesfully checked.
Is this a proper solution for client / server communication ? If yes, what do you advise me for the verfications boundaries ?
TCP already has a built-in checksum/verification. So if the message was received, it was received correctly.
Typically then, the only thing you have to worry about is figuring out how long the message is. This is done either by sending the message length at the beginning or by putting a termination character or sequence at the end.
To make sure both the sender and receiver are "on the same page" so to speak, the receiver will typically send back a response after the message was received, even if that response only says "OK".
Examples of this technique include HTTP, SMTP, POP3, IMAP, and many others.
There are several ways to do this, so I don't think there is a "proper" solution. Your solution will probably work. The one note of caution is that you need to make sure the valiation code you chose is not sent as part of the data in the message. If that is the case, you will detect that the message is complete, even though it is really not the end of the message. If that is not possible to know what the data will look like, you may need to try a different technique.
From your description, it sounds like your messages are variable length. Another way would be to make all the messages the same length, that way you know how much data is to be read each time to get a complete message.
Another way would be to send over the length of the message first (such as a binary 32 bit number) which indicates the number of bytes to be read until the end of the message. You read this first to get the amount of data, and then read that amount from the socket.
If you had a set number of messages where the length was the same each time, you could assign a number to each message and send that number first, which you could then read. With that information you can determine how much data is to be read based on the assigned number to the message.
What you select to use for a solution will probably be based on factors like if messages are varaible or fixed in length and/or do you need to send additional information with the data. In this case, you might have a mixture where you send a fixed length header, which contains the information about the data which follows; either in length or the type of data which follows.
You need to establish an application-level protocol that would tell you somehow where application messages start and end in the byte stream provided to you by TCP (and then maybe how connected parties proceed with the conversation).
Popular choices are:
Fixed-length messages. Works well with binary data and is very simple.
Variable-size messages with fixed format or size header that tells exact size (and maybe type) of the rest of the message. Works with both binary and text data.
Delimited messages - some character(s) like new-line or \x1 are special and denote message boundaries. Best with text data.
Self-describing messages like XML, or S-expressions, or ASN.1.
I have a dll written in C.
I would like to send data to a socket and receive the answer in the same function.
e.g.:
BOOL SendToSocketAndRecv(...)
{
// ...
send(...);
retval = recv(...);
// ...
}
In another word, my dll should not follow Client Server pattren.
Is this possible ?
any help ?
Thank you - Khayralla
Yes
You may work in either blocking (synchronous) or non-blocking (asynchronous) mode. Depending on this you may or may not send more data before you receive something from the peer.
"Stream" sockets (like TCP) are "tunnels". If the peer sends several packets you may receive them in a single call to recv, and vice-versa - a sinle "message" from the peer may take several calls to recv. Hence you should read the message in a loop.
You have a lot to learn about network programming.
I am sending a commands to Robot and then wait to get answer
Yes, what you have will work.
But things start to get interesting when you factor in the chance that the robot will not respond for whatever reason. Then you need to provide for a timeout on the response. Soon other things start to creep in. For example, you may not want to be stuck in the read for the duration of the wait, because you may need to service other events (user input or other sources) as they comes in.
A common architecture to handle this is to use select() and make it the hub of all your incoming events. Then you drive a state machine (or machines) off these events. You end up with an event driven architecture. It would look something like this:
while(true)
{
select(fds for event sources, timeout);
if (timeout)
{
call robot state machine(timeout);
continue;
}
iterate through fds
{
if (fd has data)
{
read data into buf
if (fd is for robot)
{
call robot state machine(buf)
}
else if (fd is for source1)
{
call source1 state machine(buf)
}
...
}
}
}
In this model, sends can be done from anywhere in the code. But you wind up sitting in the select() after, waiting for events. Also, you will have to figure out the details of doing the correct timeout and select in general, but there is enough of that out there.
Yes this is both possible and legal. The API itself isn't concerned about being used from the same function.
not only is this possible, it is a classic coding idiom for a client in a client server system. Usually the function is called something like ExecuteRequest
When we send a large amount of data to the client,its ReceiveAsync event is being called more than one time and in each time we get a few piece of the packet.
What shall we do to get C# Silverlight Tcp Packet in one piece and through one event?
Thank you in advance.
You can't. The very nature of TCP is that data gets broken up into packets. Keep receiving data until you've got the whole message (whatever that will be). Some options for this:
First send the size of the message before the message itself.
Close the connection when the message has been sent (so the client can basically read until the connection is closed)
Add a delimiter to indicate the end of the message
I generally dislike the final option, as it means "understanding" the message as you're reading it, which can be tricky - and may mean you need to add escape sequences etc if your delimiter can naturally occur within the message.
I was fiddling with Silverlight's TCP communication and I was forced to use the System.Net.Sockets.Socket class which, on the Silverlight runtime has only asynchronous methods.
I was wondering what happens if two threads call SendAsync on a Socket instance in a very short time one from the other?
My single worry is to not have intermixed bytes going through the TCP channel.
Being an asynchronous method I suppose the message gets placed in a queue from which a single thread dequeues so no such things will happen (intermixing content of the message on the wire).
But I am not sure and the MSDN does not state anything in the method's description. Is anyone sure of this?
EDIT1 : No, locking on an object before calling SendAsync such as :
lock(this._syncObj)
{
this._socket.SendAsync(arguments);
}
will not help since this serializes the requests to send data not the data actually sent.
In order to call the SendAsync you need first to have called ConnectAsync with an instance of SocketAsyncEventArgs. Its the instance of SocketAsyncEventArgs which represents the connection between the client and server. Calling SendAsync with the same instance of SocketAsyncEventArgs that has just been used for an outstanding call to SendAsync will result in an exception.
It is possible to make multiple outstanding calls to SendAsync of the same Socket object but only using different instances of SocketAsyncEventArgs. For example (in a parallel universe where this might be necessay) you could be making multiple HTTP posts to the same server at the same time but on different connections. This is perfectly acceptable and normal neither client nor server will get confused about which packet is which.