Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

I launched two more clients, each one with a different value in the Login field, and started sending some messages around:

Image Added

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. 

 

Sockets are communication endpoints; to do socket communication you need two sockets, each of which is identified by a combination of IP address and port number. 

Communication between sockets has to follow some sort of protocol, so the code at each end knows how to interpret the packets of data that arrive at the socket. There are a number of standardized port/protocol combinations, such as:

 

 

- you establish communication between two applications which may be running on the same device, or which may be on separate computers on one network, or which may be on opposite sides of the planet. In all cases,

Here's the code the server uses to begin listening:

Code Block
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:

Code Block
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. 

Code Block
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:

Code Block
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. 

Code Block
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.