Receiving Data in TCP Mode
We have already explained that RX and TX buffers operate differently in the TCP and UDP mode. This section explains how to receive data when the TCP protocol is used by the socket.
In a typical system, there is a constant need to handle an inflow of data. A simple approach is to use polling. You just poll the buffer in a loop and see if it contains any fresh data, and when fresh data is available, you do something with it. This would look like this:
sub on_sys_init
while sock.rxlen = 0
wend ' basically keeps executing again and again as long as sock.rxlen = 0
s = sock.getdata(255) ' once loop is exited, it means data has arrived. We extract it.
end sub
This approach will work, but it will forever keep you in a specific event handler (such as on_sys_init) and other events will never get a chance to execute. This is an example of blocking code that could cause a system to freeze. Of course, you can use the doevents statement, but generally we recommend you to avoid this blocking approach.
Since our platform is event-driven, you should use events to tell you when new data is available. There is an on_sock_data_arrival event that is generated whenever there is data in the RX buffer:
sub on_sock_data_arrival
dim s as string
s = sock.getdata(255) ' Extract the data -- but in a non-blocking way.
' .... code to process data ....
end sub
The on_sock_data_arrival event is generated whenever there is data in the RX buffer, but only once. There are never two on_sock_data_arrival events (for the same socket) waiting in the queue. The next event is only generated after the previous one has completed processing, if and when there is any data available in the RX buffer.
This means that when handling this event, you don't have to get all the data in the RX buffer. You can simply handle a chunk of data and once you leave the event handler, a new event of the same type will be generated.
Here is a correct example of handling arriving socket data through the on_sock_data_arrival event. This example implements a data loopback — whatever is received by the socket is immediately sent back out.
sub on_sock_data_arrival
sock.setdata(sock.getdata(sock.txfree))
s = sock.send
end sub
We want to handle this loopback as efficiently as possible, but we must not overrun the TX buffer. Therefore, we cannot simply copy all arriving data from the RX buffer into the TX buffer. We need to check how much free space is available in the TX buffer. The first line of this code implements just that: sock.getdata takes as much data from the RX buffer as possible, but not more than sock.txfree (the available room in the TX buffer). The second line just sends the data.
Actually, this call will handle no more than 255 bytes in one pass. Even though we seemingly copy the data directly from the RX buffer to the TX buffer, this is done via a temporary string variable automatically created for this purpose. In this platform, string variables cannot exceed 255 bytes.