Digi Homepage Making Device Networking Easy.
 

BSD TCP Client Sample

Introduction

This sample demonstrates how to write a TCP client application using the Berkeley Software Distribution (BSD) standard socket APIs to communicate with a device server.

For the purpose of this demonstration, the client application initiates communication with the device server by first creating a networking socket. Then using that socket, establishes a TCP connection to a single port on the device server and attempts to transmit and receive data from the device server (similar to a loopback test).

Device Server Setup

This sample was designed to operate with the first port on the device server, and requires that the port be configured to listen for and accept raw socket connections. After the device server is configured properly, the port must also have a loopback plug attached to it.

Configure the device server
  1. Access the web interface by entering the module’s IP address in a browser’s URL window.
  2. Choose Serial Ports from the Configuration menu.
  3. Configure the module to function as a TCP server by doing the following:
    1. Click the TCP tab.
    2. Check Enable TCP Server.
    3. Specify 2101 as the Raw TCP port.
    4. Click Save.
  4. Connect the loopback plug to port 1.

How To Build

This sample has been compiled and tested using GCC 3.2 on Red Hat Linux 8.0. It contains a Makefile that is used for building the application.

To build this sample
  1. Change directory to where the sample source files reside.
  2. Type make.

Step-by-Step

1.  Create a local socket

The call to create a socket looks like this:

int Socket = socket(AF_INET, Type, Protocol);

Where Type is SOCK_STREAM and Protocol is IPPROTO_TCP for a blocking, connection oriented TCP/IP socket.

2.  Bind to a local port

To bind the socket to a local port, call the following function:

bind(Socket, &SockAddr, sizeof(SockAddr));

Binding to a local port must be done before using the socket to calls like connect, and is used to associate the currently unnamed socket with a local name.

The SockAddr parameter is the struct sockaddr representation of the local name to bind to. This name consists of an address family (for TCP/IP, always AF_INET), a host address, and a port number.

In this sample, the calls to socket and bind are both done in the function MySocketOpen.

3.  Establish a connection

Connections are established by calling the connect function.

connect(Socket, &SockAddr, sizeof(SockAddr));

Where SockAddr is the struct sockaddr representation of the peer name to connect to. Because blocking sockets are being used, the call to connect will not return until the operation either fails or completes successfully.

To simplify creating a connection, this sample uses a function named MySocketConnect.

MySocketConnect(MySocket,
                AddressToConnectTo,
                PortToConnectTo);

Where MySocket is the socket returned from the call to MySocketOpen.

AddressToConnectTo is a string that represents the IP address of the device server in dotted number format (e.g. "10.0.0.1").

PortToConnectTo is the port number used by the device server for raw TCP connections to port number one. On Digi device servers this port number defaults to 2101.

MySocketConnect hides the details of converting the IP address and port number to struct sockaddr representation.

4.  Transmit data

Transmitting data is done by calling send.

send(Socket, Data, Length, 0);

After verifying the connection completed successfully, the sample uses the socket to transmit some data.

For consistency the sample provides its own function named MySocketSend.

MySocketSend(MySocket, SendData, sizeof(SendData));

The parameters needed for MySocketSend are: MySocket which is the socket returned from MySocketOpen, SendData which is a pointer to the buffer holding the data to send, and sizeof(SendData) which is the number of bytes SendData points to.

5.  Receive data

To retrieve data received at the local address, call recv.

recv(Socket, Data, Length, 0);

With the device server setup with the loopback plug, the data transmitted in the step above will be sent directly back to the sample application.

Again for consistency, the sample provides its own function, MySocketRecv

MySocketRecv(MySocket, RecvData, sizeof(RecvData));

The caller to MySocketRecv must supply the prerequisite MySocket, a buffer RecvData to hold the received data, and sizeof(RecvData) which specifies the length of RecvData.

6.  Close the socket

Accomplish this task by calling the following two functions:

shutdown(Socket, SHUT_RDWR);
close(Socket);

When the sample application is done using the socket, the connection it represents must be terminated properly (shutdown) and any resources it may be using should be released (close).

File List

hexdumpdata.cpp
hexdumpdata.h
Makefile
mysocket.cpp
mysocket.h
tcpclient.cpp

Keywords

socket; bind; connect; send; recv; shutdown; close
 
 
Digi International Inc. 11001 Bren Road E. Minnetonka, MN 55343
PH: (952) 912-3444 or 877-912-3444
FX: (952) 912-4952