I'm building an application to communicate to an Xbee module via the Xbee API.
Currently I have something working, but its fairly simple and has quite a few limitations.
Sub processPackets() ' this runs as its own thread
'remove data from serial buffer and format in to packet
'if IO response generated remotely, not requested put in IOQueue
'Otherwise put in CMDQueue (response generate from request, ie cmd response or packet Ack
End Sub
Then as an example of a typical command request Send data to serial port Loop (with timeout) checking CMDQueue for packet, dequeue and check if it matches Otherwise timeout
Now its pretty obvious the potential issues with this method. In particular, since the Xbee modules can sleep you may have to wait a considerably long time for an Ack. Plus it is dependent on order, etc.
I would like to take a non-blocking approach. In this case, in order to act on the the Ack/response packet in most cases I need to know the original packet it was sent in response to.
I'm thinking of creating a few threads. SendPacket will send the packet, load the sent packet, time sent, and timeout in to memory, also include callback function? (array?) PacketProc will parse packets, check the array of packets waiting for response and call the callback function. It will also check for any waiting packets that have timed out and call the callback to indicate timeout?
Ultimately I'm looking for the ability to send packets to multiple devices (may response in any order) and act on those responses or act on the timeout.
I'm not particularly familiar with .NET can anyone comment on this approach or recommend a better pattern to look in to? Any .Net methods I should look in to?
But all data being sent via TCP requires an ACK. Every byte sent must be accounted for, or it will be retransmitted (or the connection reset (closed), in severe cases).
What is an ACK packet? ACK is short for "acknowledgement." An ACK packet is any TCP packet that acknowledges receiving a message or series of packets. The technical definition of an ACK packet is a TCP packet with the "ACK" flag set in the header.
A missing ACK means that the TCP transmit buffer is not purged. This makes eminent sense because the stack may be required to resend the data. If the data loaded into the TCP transmit buffer is greater than half the buffer size then the next block of data cannot be loaded into the stack until an ACK is received.
TCP sends an ACK before HTTP sees the data. But an HTTP response is NOT a TCP ACK. A slightly longer answer is that TCP acks are independent of processing at higher layers in the stack on most systems. An ACK is usually sent for each window of data.
Use the Task class.
Imports System.Threading
Imports System.Threading.Tasks
...
Dim buffer As StringBuilder;
Sub processPackets() ' this runs as its own thread
' Wait for packet
' put here command/loop that waits packet
buffer.Append(packet);
'remove data from serial buffer and format in to packet
'if IO response generated remotely, not requested put in IOQueue
If buffer.ToString() = "REMOTELY" Then
' Put IOQueuo
buffer.Clear()
Else
'Otherwise put in CMDQueue (response generate from request, ie cmd response or packet Ack
' Put in CMDQueue
buffer.Clear()
End If
End Sub
...
' Create and execute the Task that will process the packets
Dim t = Task.Factory.StartNew(Sub() processPackets())
http://www.dotnetcurry.com/ShowArticle.aspx?ID=491
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With