Recombine split TCP packet with flashes

I have a program in C ++ that sends a socket of 23723 bytes to a flash player in one "shot".

A flash player sometimes receives two packets of size 17520 and 6203, and in other cases it receives one packet of 23723.

EDIT: There seems to be no way to get the total number of bytes associated with flash send data. This will make it very difficult to create a loop to recover a broken package.

I thought TCP should have recombined the packets correctly, and I am having difficulty recombining them.

This is my flash receive handler:

var socket:Socket = new Socket(); socket.addEventListener(Event.CONNECT, socketConnectHandler); socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataReceivedHandler); socket.connect("127.0.0.1", 7445); socket.writeUTFBytes("hi"); private function socketDataReceivedHandler(event:ProgressEvent):void { var socket:Socket = event.target as Socket; trace(socket.bytesAvailable); var data:ByteArray = new ByteArray(); socket.readBytes(data); } 

Command:

 trace(socket.bytesAvailable); 

it will print 23723 from time to time, and at another time it will print 17520 quickly and then 6203. The total size is just examples and can be changed for each sending socket. Also, many sockets can be sent or received at the same time, so split packets can be mixed. In C ++, I could determine what the total size of the data sent was, even if I had not yet received all the data sent.

+1
source share
2 answers

This has nothing to do with tcp. A socket can send you any number of bytes if it contains at least one byte. Thus, you can get [1, 23722]. The right way to do this is to invoke reading in a loop and fill the array yourself. If your code does not contain a loop but works, then it works randomly. This cannot work without a loop.

Edit: Do not use bytesAvailable. Check the return value of the read function. Check your code: if your code depends on bytesAvailable, this is not true.

Edit2: It seems that the flash api (which I don't know) works differently than the api socket, which uses all other frameworks and languages. I assumed that it will work the same way, so let me fix it: you should have the following loop:

 int writePos = 0; var array = ...; while true: wait for bytes to become available. i do not know how to do this but one method would be 'while bytesAvailable == 0 then sleep 10' var bytesAvailableCopy = bytesAvailable; //copy because this value can change anytime socket.read(array, writePos, bytesAvailableCopy ); writePos += bytesAvailableCopy; if(writePos == maxLength) break; 
+2
source

Okay ... try and understand this. TCP sockets are not connected with the transmission of packets over the network (at least conceptually), but in fact by a stream of bytes, which is transmitted in the same sequence that should be received at the other end, without failures.

Now the lower layers (IP, etc.) break the stream into packets and send it over the network. The TCP stack on the receiving side reassembles the packets (requests retransmission if necessary) and forms a stream from it again when and when it continues to receive packets from the lower layers. Calling the read() socket for the destination will receive the bytes received in the stream so far. Therefore, you can never be sure that a single read() call will give you all the data sent.

The trick is to use multiple read() calls. You can have two possible scenarios:

(1) When you know exactly how many bytes you should receive. Here you just keep calling read() until you get the specified number of bytes.

(2) When you do not know how many bytes you should receive. This is pretty tricky. Here you need to decide on Sentinel. So, at the end of the send, you send all the data you have to send, and then send this Sentinel. By the time I’m sure, you must have realized that at the end of the reception, you continue to read() ing until you get a Sentinel.

Never think of TCP sockets as packets. It is easy to drown when you think of them as streams.

+2
source

All Articles