Day 040 - Socket communication
Page 382 of the tutorial introduces socket programming.Â
As the tutorial explains, a socket "is a communication resource used by the applications to communicate between computers regardless of the network type".Â
Essentially, with sockets you can set up your own network communication channels to manage private communication between your applications or to connect to outside servers or clients.Â
The "WD using sockets" example shows one way to manage client/server communication. If you run the executable (which I suggest you do via Windows Explorer or a command prompt, as you'll need to run more than one copy) you'll see this window:
I started off with a server, and got this:
I then launched another instance and ran it as a client:
and got this window:
I launched two more clients, each one with a different value in the Login field, and started sending some messages around:
Note that the server apps now lists three clients (all on the same local IP address). Any message sent from one of the clients goes to the server and is then broadcast back to all clients.Â
Here's the code the server uses to begin listening:
PROCEDURE ListenConnections() sChannelName is string sThreadName is string // Wait for connections LOOP Multitask(-2) IF SocketWaitForConnection(csNameListeningSocket) THEN // New request for connection // Accept the connections sChannelName = SocketAccept(csNameListeningSocket) // Check the acceptance operation IF sChannelName~="" THEN Error("Unable to create the socket for the new connection",ErrorInfo()) BREAK ELSE // Start a thread to manage this connection sThreadName = sChannelName ManageConnection(sChannelName) END END END
This code is waiting for the following to execute on the client:
Multitask() // Display the connection settings in the window title bar MyWindow..Title = gfsLogin+" on the server: "+gfsServer // Connecting to the server SocketConnect(csSocketName,cnCntPort,NetIPAddress(gfsServer)) IF ErrorOccurred THEN // Error during the connection Error("Unable to connect to the server",ErrorInfo()) Close END // Run the thread for incoming messages Receive()
Both the client and the server use threading to handle the socket communications. The server runs the ManageConnection procedure, which runs on its own thread. This code is a loop that listens for incoming messages which can be a command ("BYE") or a message which gets rebroadcast via the ManageMessage procedure.Â
PROCEDURE ManageConnection(sConnectionName) sMessage is string sIp is string = SocketClientInfo(sConnectionName,SocketAddress) // Read the messages LOOP IF EventWait("TERM",5) THEN BREAK UpdateTable(sConnectionName,sIp) sMessage = SocketRead(sConnectionName,False,10) SWITCH sMessage CASE "BYE" : // User exit BREAK CASE "" : // Non-locking read operation, back to the loop Multitask(-1) OTHER CASE : // Message to post ManageMessage(sMessage) END END // Closing the socket SocketClose(sConnectionName)
ManageMessage simply loops through its list of connections and sends out the message:
PROCEDURE ManageMessage(sMessage) CriticalSectionStart("Management") sSocketName is string // Send the message to all connected users FOR ALL ROW OF Table1 // Retrieve the name of the socket sSocketName = Socket // Check the existence of this socket IF SocketExist(sSocketName) THEN // Send the message SocketWrite(sSocketName,sMessage) END END CriticalSectionEnd("Management")
Back on the client side, the Receive procedure (which is also running on a thread) sits and waits for incoming messages, displaying them as they arrive.Â
PROCEDURE Receive() sMessage is string // Wait for messages as long as the thread is not stopped LOOP // Wait and read the next message WHEN EXCEPTION IN sMessage = SocketRead(csSocketName,False,20) DO Error("Problem with inbound socket",ExceptionInfo()) BREAK END IF NoSpace(sMessage)<>"" THEN // Add the message to the end of table TableAddLine(Table1,sMessage) END Multitask(-2) END
There's more code, but that's the heart of what's going on in the sockets example.Â
I'm assuming the underlying protocol is TCP, since there's a separate way to create UDP sockets in WinDev. TCP and UDP are two of the most common transport protocols, and are lower level than application protocols such as HTTP, SMTP, FTP etc. So this is a pretty low level way of communicating between applications/devices. WinDev does have built in support for some of the higher level protocols (such as email and FTP) so it's not like you have roll your own protocols in all situations.
When communicating between two WinDev apps, it's recommended that you use the WinDev standard for determining message size, which is to begin with the size of the message, followed by <CR>, followed by the message. You can also use a delimiting character - see the help on SocketChangeTransmissionMode for more.
Besides TCP and UDP support, there are socket functions for establishing SSL, infrared and Bluetooth connections. See the socket functions page.
The tutorial itself has very little to say about how socket communications work, but the example is well worth a look.Â