Multi send() or receive() in TCP - c#

I would like to do some client and server to sharing files each other. I have an issue, because TCP "messages" are merged, despite I set how many bytes I would like to send and how many receive.
I had a look on it, and the problem occurs when in the first "message" I send a filename and after that (in new Send()) I send the file content, for example.
I fixed it by sending a feedback message after each receive packet currently.
Is there any better way to do that?

Add a length prefix to each message. And then read in a loop until you receive as many bytes as you want.

Related

Will data/buffers sent to a client before client receives/reads it merge into one?

While using a TCP based connection if I send some data to a client but because of lag or some reason the client do not reads the data. Will the data merge (Socket.Avalialbe = previous request + new request) and Socket.Recieves both buffers combined or will I need to call Soocket.Receive twice to receive the data in order that I sent it in?
It is possible that in one 'recv' you will get all the bytes that were sent across with two 'sends'.
TCP does not maintain message boundaries. It's upto the application to make sense of the data. You cannot assume that one 'send' will result in one 'recv'. Bytes received will be in TCP's buffer until application calls 'recv'.

TCP messages arrival on the same socket

I've got a 2 services that communicate using a TCP socket (the one that initiates the connection is a C++ Windows service and the receiver is a C# TCP stream) and (let's say that they might not use the same TCP connection all the time). Some of the time I'm getting half messages (where the number of bytes is miscalculated somehow) on a great network load.
I have several questions in order to resolve the issue:
Can I be sure that messages (not packets...) must follow one another, for example, if I send message 1 (that was received as half), then message 2, can I be sure that the next half of message 1 won't be after message 2?
Please have separate answer for the same TCP connection between all messages and not having the same TCP connection between them.
Is there any difference whether the sender and the receiver are on the same station?
TCP is a stream protocol that delivers a stream of bytes. It does not know (or care) about your message boundaries.
To send the data, TCP breaks the stream up into arbitrarily sized packets. [it's not really arbitrary and it is really complicated.] and send these reliably to the other end.
When you read data from a TCP socket, you get whatever data 1) has arrived, and 2) will fit in the buffer you have provided.
On the receive side you need to use code to reassemble complete messages from the TCP stream. You may have to write this yourself or you may find that it is already written for you by whatever library (if any) you are using to interact with the socket.
TCP is a streaming protocol, it doesn't have "messages" or "packets" or other boundaries. Sometimes when you receive data you might not get all that was sent, other times you could get more than one "message" in the received stream.
You have to model your protocol to handle these things, for example by including special message terminators or including a fixed-sized header including the data size.
If you don't get all of a message at once, then you have to receive again, maybe even multiple times, to get all the data that was sent.
And to answer your question, you can be sure that the stream is received in the order it was sent, or the TCP layer will give you an error. If byte A was sent before byte B then it's guaranteed that they will arrive in that order. There is also no theoretical difference if the sender and receiver is on the same system, or on different continents.

C# Packet sending using TCP streams

I'm trying to send multiple packets from a tcp server to a client using only read and write from the base "Stream" class. The problem is, I don't know what the size of the packet will be (client side). Should I send and int (4 bytes) before each packet so the client can ajust the buffer and receive only the nuber of bytes specified? I feel like there's already something in the tcp protocol that handles that but I can't seem to find it.
The process for what you are wanting to do is called Message Framing and there is no built in mecinism in TcpClient that does this for you. It is the responsibility of the higher level application layer to do it, be it your own code appending the length on the prefix of the message or some other library that handles message framing for you like WCF.
Here is a full example showing a length prefixed implementation like you suggested in your question.

How do you know if a Socket.Send() has worked?

Quite a simple question - I've been having some TCP packets go missing (they aren't received by the remote socket), so I'm considering resending any packets that don't get received.
However I need to know when send doesn't work in order to do this! I know Send() returns an integer containing the 'The number of bytes sent to the Socket', but even when the other computer receives nothing, this is always the length of the entire buffer, indicating that everything was (theoretically) sent. I also know there's a Socket.Connected property, but that is false even when that data is received, and sometimes true even when it isn't, so that doesn't help either.
So how do I know if Send() has worked?
Send() simply places the data in a buffer for the network adapter to process. When Send() returns, you have no guarantee that a single byte has "left" your computer, even when the socket is in blocking mode.
TCP ensures though that within a connection all data is received in the order it was sent. It never "forgets" a packet in the middle of a conversation, and automatically retransmits data when needed.
To determine whether retransmission is required, the protocol sends acknowledgement messages, but:
you can't access them from the Socket class
hosts may postpone sending this ACK message
The easiest way to ensure your message has arrived is to let the other party respond to them yourself. If you don't receive a response within a reasonable amount of time, you could treat that connection as broken.
About the whole discussion between Sriram Sakthivel and "the others" - I've had similar problems of receiving duplicate messages and missing others, but in my personal case this was caused by:
using BeginReceive() (the async receive method),
reusing the same buffer on each BeginReceive() call, and
calling BeginReceive() before processing that buffer, causing the buffer to be filled with new data before having read the old message.
The ideal way of doing this is to check if the bufferedAmount is zero after you've sent a message. The trick is, you'll have to let your application know you are in fact sending a message.

Socket Data Handling -for data packing (TCP)

I'm working on a socket project. I want to send ~4kb data with TCP. I need to ask a question in here. That is: If I send ~4kb data with TCP, may my data handler function receives this data in one more time? Namely can RECEIVE(server-side) function return 2 times (If I send ~4kb data once)? If I can understand this, I'll start to make my own packet handling system.
In short: yes.
TCP transfers a stream of bytes, there is no mention of messages (and their boundaries) in a TCP connection. Even if you send two bytes they can be received in two separate chunks (theoretically of course; it's quite unlikely in practice). So you should put some marks into your data stream. I'd suggest writing a "message header" before every message where the header contains at least length of the following message's body. And take care, the header itself may also be fragmented when receiving.
TCP is a stream protocol. You receive a stream of bytes in the order you sent them. To reconstruct the message you should either prefix every message with the length of the message or use a delimiter to mark end of the message.
I don't know your business requirements but you could use a binary protocol like MQTT or a text based protocol like STOMP.

Categories