Read(0) behaviour


Recommended Posts

Hi,

I'm having a few difficulties with a TCP connection and just want to understand the Read(Num Bytes) function a bit better.

I'm only using Read(0) to get whatever is in the buffer and then process since there is no EOL byte to look for, and the receive packets come in asynchronously and are various sizes. My question is, when I call Read(0) and there is TCP data coming in at that instant, will it wait for the current TCP packet to finish then return that data, or is there any chance that it may return only part of the incoming packet, and I'll get the rest on the next Read()? I guess it's the same as asking if TCP packets are read as a single block per received packet or as a stream? I have very little understanding of how Windows manages its buffers, so forgive me if the answer is obvious.

Am I correct in assuming that the timeout is ignored when using Read(0) function?

Reason for my question is that I'm currently appending data from Read(0) to a buffer, then searching through to find responses and removing from buffer. It would be easier if I could just read the TCP response, process and discard rather than having to manage a constantly expanding and shrinking buffer. I seem to be getting artifacts left in the buffer that are never removed.

Hope this all makes sense

Regards

Andrew

Link to comment
Share on other sites

The actual TCP comms and the buffer that Read() accesses are pretty much completely de-coupled. The TCP comms runs in its own thread, so you have no predictability in terms of TCP packets. So, basically you'll have to use your own buffer to process through. Personally I'd create an array out of the bytes rather than use a string for this buffer.

Yes, read(0) ignores the timeout and returns immediately, with or without any data.

Link to comment
Share on other sites

Thanks, just as I suspected.

I'm using arrays as you suggest but am getting artifacts left in some of the buffers. (random data left in the buffer after a period of processing that never gets removed)

I have incoming data from up to 4 identical devices, originally I tried creating a 2D array, with each row holding the data from each device, however this didn't work. Something to do with array dimensions. It might work if I transpose data back and forth but this seemed a slow way to do it.

global Buffer = fill(0,4)
for(private i=0, <NumReaders, i++)
	  try
		 pDevice = CommDevice[i][RADIO_PORT]
		 Buffer[i] = Concat(Buffer[i],AscA(pDevice.Read(0)))
	  catch()
		 Buffer[i] = 0
	  endcatch
// process buffer here, if matching data found do something with it then remove from buffer
Buffer[i].RemoveAt(Index, NumBytes)

I currently have something a bit less elegant but works better, in part

global Buffer0 = 0
global Buffer1 = 0
global Buffer2 = 0
global Buffer3 = 0

for(private i=0, i<NumReaders, i++)
	  try
		 pDevice = CommDevice[i][RADIO_PORT]
		 switch
			case (i==0)
			   pBuff = Buffer0
			case (i==1)
			   pBuff = Buffer1
			case (i==2)
			   pBuff = Buffer2
			case (i==3)
			   pBuff = Buffer3
			default
			   throw()
		 endcase
		 pBuff = Concat(pBuff,AscA(pDevice.Read(0)))
	  catch()
		 pBuff = 0
	  endcatch

// process pBuff and remove matching data, then copy back to original buffer
	  switch
		 case (i==0)
			Buffer0 = pBuff
		 case (i==1)
			Buffer1 = pBuff
		 case (i==2)
			Buffer2 = pBuff
		 case (i==3)
			Buffer3 = pBuff
	  endcase

Strangely, I'm only getting artifacts in Buffer1, 2 & 3 but not Buffer0, which is why I suspect the code, rather than the device itself. Is it possible that this double handling might be causing some artifacts to be left over?

Regards

Andrew

Link to comment
Share on other sites

I can't say, but I don't see why you are doing this double copying in the first place. Personally, since you obviously know what you are doing with objects, I'd just create an object for your buffer and instantiate it four times. Then you could have an array with the four buffers, pass them around as need be, but still only have a 1D array for the actual data that you need to process inside each instantiated object. This would be much cleaner.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.