Socket Interface I
The Socket Interface (Version
575.9.25) ;-)
On this page: Client-Server, The
socket variable, socket
functions, Network or Host order, Blocking
functions, Stream or datagram, Implementation
in EC32
Descriptions regarding the socket interface have already been published
hundreds of times. Nevertheless, for completeness, here is another output.
The socket interface, as a new functionality in the PC environment; has been deleveloped already more than 15 years ago for the BSD-Unix 4.2 and was known as
the Berkley Socket Interface. In the following years many systems have adopted
this interface.
Nowadays winsock.dll is an integrated part of for instance Windows 95. The
implementation not only allows the creation of new internet applications but
also simplifies the migration of unix application to a Windows based platform.
Client Server
Internet applications are mostly created based upon the client server
principles. The client serves as an user interface and requests certain services
from the server. It establishes depending on user events connections to the
server and could be seen as the active part.
The server provides services. It has to be permanently in the operating
condition to accept and grant requests, it could be seen as the passive part. A
server never requests services from a client.
This behaviour creates some significant differences, which are mirrored in
different interface commands.
Integration of socket functions in C
In order to use the winsock.dll in your own applications, you got to include
the appropriate file in your application:
#include <winsock.dll>
The file contains all declarations regarding data types, constants and
function prototypes. If you are developing 16 bit applications you are using winsock.dll, for 32 bit applications wsock32.dll. You have to include one of the
DLL's in your project.
The socket variable
The socket variable is an integer. It is definitely not the portnumber of the
application rather than a handle, like a file handle, for a connection. Using
this handle you may ask for certain information regarding the connection, which
belongs to this handle.
Most
important socket functions.
Depending on the development tool the range of the available functions may
vary. Sometimes you find undocumented functions. The following table shows some
functions, which are common in most of the versions.
| Function |
Description |
| accept |
accepts (in a server) a new connection and provides a new
socket for this connections |
| bind |
binds a socket to a local IP address and a port |
| closesocket |
closes a socket |
| connect |
establishes a connection between two sockets |
| getpeername |
returns the IP address of the adjacent node from a socket |
| getsockname |
returns the own IP address from a socket |
| getsockopt |
reads the active flags from a socket |
| ioctlsocket |
sets certain socket option flags |
| listen |
creates a queue for incomming connections |
| recv |
receive data from a socket |
| recvfrom |
receive data from a socket and read sender |
| select |
checks the status of one or more sockets |
| send |
send data via an existing connection |
| sendto |
send data using an address |
| shutdown |
suppresses further receiving or transmitting data |
| socket |
creates a new socket |
Network or host
order?
Everybody how has done his (hers of course too) own development has been
confronted with the problem of the byte order. The roots of this problem are to
be found in the different ways, depending on the different systems
architectures, how the memory is interpreted, if the pointer to the memory is
not treated as a byte rather than as a WORD or a LONG. For using the same data
not only on Intel based systems but only on a Macintosh, a ceratin
standardization had to be found.
The Network order (also called Big-Endian) implies, that the most significant
byte is transmitted first followed by the least significant byte.
| Memory |
Little Endian
(Host Order) |
Big Endian
(Net Order) |
Little Endian
(Host Order)
|
Big Endian
(Net Order)
|
| n+3 |
|
|
31...24 |
7...0 |
| n+2 |
|
|
23...16 |
15...8 |
| n+1 |
15...8 |
7...0 |
15...8 |
23...16 |
| n |
7...0 |
15...8 |
7...0 |
31...24 |
| |
16 Bit WORD |
32 Bit WORD |
As all Intel based PC are using their memory according to the Little Endian,
we have to convert all variables of the type WORD or LONG into Net order before
we can use them with commands to the driver. Vice versa all data of the same
types, which are supplied by a driver, have to be converted into the Little Endian before being used for calculations.
There are some functions in the socket interface which provide conversions:
| Function |
Description |
| htonl |
32 Bit integer: host --> net order |
| ntohl |
32 Bit integer: net --> host order |
| htons |
16 Bit integer: host --> net order |
| ntohs |
16 Bit integer: net --> host order |
| inet_addr |
converts IP address from ascii string to long |
| inet_ntoa |
converts IP address from long to ascii string |
If you want to know about the term Endian
Blocking functions
All functions of the socket interface are blocking functions, e.g. the
function being called will return only after complete execution.
Especially in a multi tasking environment with cooperative functionality like
EC32 this would be not acceptable since other time critical functions may be
slowed down.
In order to avoid this blocking mechanism it is mandatory to call a special
function select() prior to calling any write or read function. Select return,
whether the desired function would block or not for a given list of sockets.
Streams or datagrams
Before creating a new socket, the programmer must decide, whether he is going
to use a stream or a datagram socket. This decision will have the very important
impact to use TCP or UDP. Depending on the application each of the two ways has
its own benefits. The most common way would be to create a stream (TCP) socket.
Having built a stream socket makes all measures for data security obsolete. As a
disadvantage with rapidly changing connections all functions for creating and
closing a connection have to be used very frequently causing a high overhead.
UDP on the other side is faster, but offers no mechanisms for data security.
EC32 has built in mechanisms in its UDP driver. The overlaid application will
not be bothered with these concerns.
Stream functions
| Client |
Server |
| socket() |
socket() |
| connect() |
bind() |
| |
listen() |
| |
accept() |
| send() |
recv() |
| recv() |
send() |
| closesocket() |
closesocket() |
UDP functions
| Client |
Server |
| socket() |
socket() |
| bind() |
bind() |
| send() |
recv() |
| recv() |
send() |
| closesocket() |
closesocket() |
Implementation in
EC32
Very often we were asked "Why
do you use the unsecured UDP layer instead of the secure TCP"? There
are different reasons:
-
TCP requires to establish a connection between
two sockets in the two adjacent host systems. The first development for
network communication in this scenario was done using a 16 bit real mode
platform by the name of ASA, which only had limited memory. It was found,
that the ressources for that socket could not be re-gained after a
connection was accidently interrupted and a new socket had to be created. If
this was repeated several times, which is quite normal for an unattended
system, the software was running out of memory. So Volkswagen had made the
decision to use UDP for their internal FIS environment.
-
The overhead of TCP is much higher due to the
security mechanisms and causes a lower overall troughput.
-
The most important reasons are found in the
different implementation requirements. With TCP we have to define whether
the driver will be a client OR a server. Using unattended systems on the
other hand requires, that each system could close and re-open a connection
at any time regardless, whether the connection was closed by controlled and
pre-defined functions or was accidently interrupted due to power failures or
simply because somebody pulled the connector.
-
With TCP the sequence of operations is:
| Client |
Server |
| socket() |
socket() |
| connect() |
bind() |
| |
listen() |
| |
accept() |
| send() |
recv() |
| recv() |
send() |
| closesocket() |
closesocket() |
-
The server has to do a listen(), accept() and
then loops on the recv(). If the connection is interrupted uncontrolled, the
server never will be aware of the fact, that the client has restarted and
requires a new connection. On the other hand, there are no functions on the
client side to open a connection without the functionality provided by the
server.
In older version of EC32 we have been using an external TCP stack provided by
FTP. Unfortunately FTP did not provide libraries for DOS using 32 Bit and we had
to make a rather complicated interface built by an 16 Bit Multiplex TSR.
Furthermore each installations required a specific and time consuming
installation of the TCP software plus a license which had to be purchased from
FTP.
Today EC32 has its own internal TCP stack and does not require any additional
installation of network software. We have access to all software sources and are
free to make our own modifications, enhancements if necessary or new
implementations.
EC32 supports up to 32 concurrent host systems, TCP, UDP, TELNET and FTP
functions.
We have not been asked yet, to provide services for a WEB client or a mail
service, which would also be possible. Ask for further information.
All required data is stored in parameter files, for example in EC.ECD :
======================
# Ethernet adapters
#=====================
[ Ethernet ]
Number of ethernet adapters = 1
#
# Valid Types:
# "SMC8XXX" , "3COM3C503",
# "NE2000" , "NE2000PCMCIA",
# "3COM3C509", "3COM3C589PCMCIA",
# "SMC91C9X" , "SMC91XPCMCIA",
# "LANCE" , "ETHEREXPRESS",
# "CS89X0" , "PACKET",
# "LOOPBACK" , "SLIP_UART",
Board type = 3COM3C509
Board IRQ = 10
Board IO address (hex) = 300
Own IP address = 148.203.147.174
Subnet mask = 255.255.252.0
Number of default gateways = 1
Default gateway 1 = 148.203.147.1
Additional Options = TELNET, FTP
and in REM_HOST.CFG
[ Number ]
Number of UDP connections = 1
#
[ WaitResp ]
Number of MilliSeconds to wait = 1000
#
[ Connection ]
# Port 1
Board= 0
Port = 4000
Number of addresses = 2
Adr 1 = 148.203.147.98
Adr 2 = 148.203.147.107
On this page: Client-Server, The
socket variable, socket
functions, Network or Host order, Blocking
functions, Stream or datagram
|