Sending TCP and UDP Data
|Top Previous Next|
In the previous sections, we have explained how to handle an incoming stream of data. You could say it was incoming-data driven. Sometimes you need just the opposite — you need to perform operations based on the sending of data.
Sending data with on_sock_data_sent event
Supposing that in a certain system, you need to send out a long string of data when a button is pressed. A simple code for this would look like this:
The code above would work, but only if at the moment of code execution the necessary amount of free space was available in the TX buffer (otherwise the data would get truncated). So, obviously, you need to make sure that the TX buffer has the necessary amount of free space before sending. A simple polling solution would look like this:
Again, this is not so good, as it would block other event handlers. So, instead of doing that, we would employ a code that uses on_sock_data_sent:
When we press the button, on_button_pressed event is generated, so now the system knows we have a string to send. Using sock.notifysent we make the system fire the on_ser_data_sent event when the necessary amount of free space becomes available. This event will only be fired once — and will be fired immediately if there is already enough available space.
Within the event handler for this event, we put the data in the TX buffer and start sending it.
UDP datagrams are generated as you create them
In Using Buffers in TCP Mode we have already explained that for UDP you have a complete control over how the data you are sending is divided into the UDP datagrams. Each time you use the sock.send method you draw the boundary between the datagrams- the previous one is "closed" and the new one "begins". You can even send out an empty UDP datagram by executing sock.send without using the sock.setdata first.
Correctly responding to the sender of each UDP datagram
With UDP, your socket may be receiving UDP datagrams from several different hosts. When the on_sock_data_arrival event handler is entered (see Receiving Data in UDP mode) the following properties automatically reflect the source of the current datagram- sock.remotemac, sock.remoteip, and sock.remoteport. Additionally, the sock.bcast property will tell you whether the datagram was a regular or a broadcast one (this material has already been covered in Checking Connection Status).
Additionally, any datagram that was generated and sent from within the on_sock_data_arrival event handler will be send to the sender of the datagram for processing of which the on_sock_data_arrival event handler was entered.
The point is that if you are sending out a datagram from within the on_sock_data_arrival event handler you are automatically replying to the sender of the datagram being processed. The following example sends back "GOT DATAGRAM FROM xxx.xxx.xxx.xxx" string in response to any datagram received by the socket:
For the above example, even if several hosts send the datagrams to the socket at the same time each one of these hosts will get a correct reply back!
Now consider this example: each time the button is pressed the same message is generated:
The difference is that when you press the button the datagram will be sent to the destination, from which the most recent incoming UDP datagram was received (and accepted) by the socket!