EthernetTCPServer
This code will serve up to eight simultaneous TCP clients. The client program located on your PC sends a text message to the PIC host, which then sends a confirmation message back to the client application. The sample program uses DHCP and also allows you to ping the Ethernet device.
An interesting feature is the use of the NBNS module. When using DHCP, the IP address of the unit may change each time it is connected to the network. So how do we connect if the IP address may change each time the unit is connected? The NBNS module allows you to assign a host name to the device. In the example shown, the TCP client does not have to know the IP address of the device. Instead, you can connect using "swordfish", as shown in the image to the right. As mentioned earlier, the code will support up to eight simultaneous clients. This means you can start eight unique instances of the client application on your PC. Each one can communicate with the PIC using an independent socket. If the IP address is known or fixed (that is, you are not using DHCP) then you can enter the IP address into the "Hostname or IP Address" field, rather than using the default NetBIOS name of "swordfish". You can download a simple client program to test the code from here:
Download TCP Client Application »
Here is what you need to do to test the program
- Plug a network cable into your board and connect to your network. For example, just plug your Ethernet board into your broadband router, which will act as a DHCP server.
- Compile and then program the code into your device.
- Start the Swordfish Serial Communicator plugin, and a connect to your MCUs USART at 115200 baud.
- Reset the MCU.
If all goes well, something like the following should be displayed in the Serial Communicator window
Waiting for DHCP... Host Name : SWORDFISH MAC Address : $00 $04 $A3 $00 $00 $00 IP address : 192.123.223.1 Mask : 255.255.255.0 Gateway : 192.123.223.254
You should now be able to execute and connect up to eight instances of "TCPClient.exe".
Sample Code
// device and clock - code will work on an 18F452 as well... Device = 18F4680 Clock = 20 // important configurations... #option ENC28J60_CS = PORTD.6 #option NET_ICMP = true // enable ping #option NET_DHCP = true // enable Dynamic Host Configuration Protocol (DHCP) #option NET_NBNS = true // enable NETBIOS #option NET_TCP = true // enable TCP Include "NETApp.bas" // always first! // TCPIP stack specifics... Include "NETTypes.bas" Include "NETUtils.bas" Include "Tick.bas" Include "TCP.bas" // program helpers... Include "NETAppDisplay.bas" Include "usart.bas" Include "convert.bas" // maximum number of TCP server sockets Const MaxSockets = MAX_TCP_SOCKETS // found in NETConfig, default is eight // state machine constants... Const SM_HOME = 0, SM_LISTENING = 1 // structure that holds socket state, connected flag and // TCP socket ID... Structure TSocket State As Byte Connected As Boolean ID As TCP_SOCKET dummy As Byte // 4 byte align End Structure // TCP server socket array... Dim Sock(MaxSockets) As TSocket { **************************************************************************** * Name : TCPServerInit * * Purpose : Prepare socket array * **************************************************************************** } Sub TCPServerInit() Dim Index As Byte Dim Socket As TSocket For Index = 0 To MaxSockets - 1 Socket.ID = INVALID_SOCKET Socket.Connected = false Socket.State = SM_HOME Sock(index) = Socket Next End Sub { **************************************************************************** * Name : TCPServerOpen * * Purpose : Open for listening 'MaxSockets' TCP sockets * **************************************************************************** } Sub TCPServerOpen() Const SERVER_PORT = 9760 Dim Index As Byte Dim Socket As TSocket For Index = 0 To MaxSockets - 1 Socket = Sock(index) If Socket.ID = INVALID_SOCKET Then Socket.ID = TCPListen(SERVER_PORT) If Socket.ID <> INVALID_SOCKET Then Socket.State = SM_LISTENING EndIf EndIf Sock(index) = Socket Next End Sub { **************************************************************************** * Name : TCPServerTask * * Purpose : Process the TCP server sockets * **************************************************************************** } Sub TCPServerTask() Dim c As Byte Dim Index As Byte Dim Socket As TSocket For Index = 0 To MaxSockets - 1 Socket = Sock(index) // server socket allocated... If Socket.State = SM_LISTENING Then // see if a client has disconnected... If Not TCPIsConnected(Socket.ID) Then If Socket.Connected Then Socket.Connected = false Write("Client ", DecToStr(Socket.ID), " disconnected",13,10) EndIf Sock(index) = Socket Continue EndIf // see if a client has just connected... If Not Socket.Connected Then Socket.Connected = true Write("Client connected, ") TCPGetRemoteInfo(Socket.ID) Write("IP address is ") DisplayIPAddress(TCP.RemoteInfo.Remote.IPAddr) EndIf // receive and display any bytes sent... If TCPIsGetReady(Socket.ID) <> 0 Then While TCPGet(Socket.ID, c) Write(c) Wend Write(13,10) // transmit a reply... If TCPIsPutReady(Socket.ID) <> 0 Then TCPPutString(Socket.ID,"Message from server : " + DecToStr(TickGet)) EndIf EndIf EndIf Sock(index) = Socket Next End Sub // program start... SetBaudrate(br115200) TCPServerInit() #if NET_DHCP Write("Waiting for DHCP...",13,10) #else TCPServerOpen() #endif // loop forever... While true // This task performs normal stack task including checking for incoming // packet, type of packet and calling appropriate stack entity to process it. NETApp.Task TCPServerTask() // If DHCP is enabled, display configuration when a DHCP event // has occurred - also open our TCP server sockets for listening... #if NET_DHCP If NETApp.DHCPEvent() Then DisplayConfig() TCPServerOpen() EndIf #endif Wend