Socket: 1 Introduction

Up: GEOS SDK TechDocs| Up | Prev: Socket | Next: 2 Simple Example

The Socket library manages communications both between machines and between threads on the same machine. It provides a level of abstraction above individual communication protocols ( e.g. , IrLMP, TCP/IP). Programs using the Socket library can send and receive information packets without knowing much about the communications protocol by which those packets are being transmitted. Also, programs using the Socket library need not know about the hardware communication ports used -- whether communication is being carried out over an IR serial port, a modem, or a network connection -- the API is the same.

The Socket library supports different "delivery types"-- different levels of reliability in transmitting data. There is a trade-off: the more reliable delivery types require more set-up work by the programs using them. The following delivery types are available:

Datagram
Unreliable transmission of discrete packets. Packets may arrive out of order or not at all. It is up to the data sender to determine if re-transmission is necessary. This is the least demanding delivery type to set up, because it doesn't require any two-way connection.
Sequenced Packet
Sequenced Packet delivery means reliable transmission of discrete packets. The packets arrive in the order sent. The Socket library manages error checking and re-transmissions, as necessary. The program using a sequenced packet socket is responsible for establishing a two-way communications connection.
Stream
Stream delivery means the reliable transmission of a stream of bytes, as opposed to other delivery types which require that data be broken up into packets. The Socket library manages a stream of bytes, breaking it up into packets, transmitting the packets, and reconstructing the byte stream from packets on the other side. The Socket library also manages error-checking and re-transmission, as necessary. The program using a stream socket is responsible for establishing a two-way communications connection.

Addresses

Each side of the connection is represented by an address. An address is made up of several parts:

Domain
The network over which the connection is being made. Domains include TCP/IP, IRLAP, and "loopback" (used for connections between two threads on the same machine).
Address Data
This data identifies a machine on a network domain. The format of the address depends on the domain. In the case of TCP/IP, a sample address might be the string "geoworks.com". IrLAP addresses are 32-bit numbers. If the domain is "loopback", then no address information is necessary -- the sending and receiving machines are one and the same.
Port
This token identifies one side of a connection within one machine. Ports allow multiple data sockets to operate over one connection. Thus, connecting to "geoworks.com", one might send mail messages using port 25 and file-transfer commands via port 21. Port numbers are either 16-bit or 32-bit, depending on the domain.

The amount of overhead associated with sending and receiving data depends upon the devices involved, the domain, and the delivery type. When testing, experiment with different domains (if available), delivery types, and packet sizes to find a good balance of reliability and rapidity.

For any domain, there may be more than one address format. For instance, the TCP/IP address "geoworks.com" is conveniently human-readable, but cannot be used at the socket level to actually make a connection. Instead, you must resolve "geoworks.com" to a 32-bit address number. All socket operations require "primitive" addresses -- addresses resolved to their simplest form. To resolve an address, call SocketResolve() . We will discuss the details of working with addresses in more detail below.

Errors

Many of the Socket library routines return error values. Sometimes these error values are return values of routines; if you call a routine that can return an error value, be sure to check the return value and react appropriately to errors. Some routines don't return an error value directly, instead returning a flag to indicate that something has gone wrong. To find out exactly what went wrong, call ThreadGetError() .

Those Socket library routines that return error values do not set the thread error value. Calling ThreadGetError() after calling such a routine would not detect any error encountered by that routine.

ThreadGetError() returns a word-sized value. The low byte of this word is a SocketError value; the high byte is a SpecSocketDrError value. If the returned word is zero, that means that there was no error.

In general, a SpecSocketDrError value indicates a low-level error, and a SocketError value indicates a high-level error. In many cases, there will be a SocketError in the low byte, but the high byte will be clear -- there was no problem with the low-level communication medium, but a protocol exception may have occurred.

In general, only the low byte (the SocketError value) is useful in determining how to handle the exception. The high byte might affect what error message is displayed to the user. For example, it probably doesn't matter to your program whether the high byte was SSDE_LINE_BUSY or SSDE_NO_DIALTONE. In either case, it just means that communication could not be established. However, users might want to know the nature of the problem so that they can figure out how fix it.

Some of the more common SocketError values are listed below. In addition, certain routines may make use of other SocketError values, which will be discussed with those routines.

SE_NORMAL
There is no error. SE_NORMAL is guaranteed to equal zero.
SE_OUT_OF_MEMORY
The Socket library ran out of memory. Perhaps it was trying to receive or send a data packet that was too large.
SE_SOCKET_IN_USE
The socket was busy doing something else. Perhaps you tried to connect it, but it was already connected.
SE_SOCKET_BUSY
The socket was temporarily busy doing something else. Perhaps you should try again a few times.
SE_MEDIUM_BUSY
The hardware port which would be used to carry out the requested operation was busy. You might wait for the hardware port to become free; you could call SocketCheckMediumConnection() to see if the port is being used for a socket connection.
SE_ALL_PORTS_BUSY
To carry out the requested operation, the Socket library tried to use a port number; however all port numbers were already busy.
SE_SOCKET_NOT_BOUND
The socket was not bound ( i.e. , associated with a port number), but needed to be bound to carry out the requested operation. To bind a socket, call SocketBind() .
SE_SOCKET_NOT_LISTENING
The socket wasn't listening for incoming connections, and needed to be in this state to carry out the requested operation. To make a socket listen, call SocketListen() .
SE_SOCKET_LISTENING
The socket was busy listening for incoming connections when you asked it to carry out another operation. Remember that you often want separate sockets to handle listening and data transfer.
SE_SOCKET_NOT_CONNECTED
The socket was not connected, but a connection is required for the operation you requested. To connect the socket, call SocketConnect() .
SE_SOCKET_CLOSED
The socket was closed, making the requested operation impossible.
SE_CONNECTION_CLOSED
The other side of your socket's connection has closed that connection; to close up your side of the connection, call SocketClose() .
SE_CONNECTION_FAILED
The connection was lost, probably due to some low-level link failure. There may have been a problem with the physical connection or with the domain-specific software.
SE_CONNECTION_RESET
The connection was lost, probably due to this side of the connection intentially making a low-level disconnection; e.g. , the sort of disconnection that results from SocketCloseDomainMedium() or the Socket's owning thread exiting.
SE_TIMED_OUT
The Socket library was unable to carry out the requested operation before the time-out time was reached. Beware: Depending on the domain, for certain phases of certain operations, there may be low-level time-outs which can occur even if you have specified a longer or an infinite time-out.
SE_CANT_LOAD_DRIVER
The Socket library was unable to load a driver necessary to carry out the requested operation.
SE_UNKNOWN_DOMAIN
The Socket library didn't recognize the domain name.
SE_DESTINATION_UNREACHABLE
The requested destination address was unreachable over the network.
SE_LINK_FAILED
The low-level link used for this connection failed or could not be established. There may have been a problem with the physical connection or with the domain-specific software.
SE_SYSTEM_SHUTDOWN
This error signals that GEOS is shutting down. Your program should probably either end its connections gracefully or attempt to delay the shutdown. Note that it is possible for a shutdown to occur without generating this signal.
SE_INFO_NOT_AVAILABLE
The requested information was not available.
SE_DOMAIN_REQUIRES_16BIT_PORTS
You tried to use a 32-bit port number in a domain that does not support them. Use MANUFACTURER_ID_SOCKET_16BIT_PORT as the ManufacturerID of your port number.
SE_INTERRUPT
The operation was stymied by SocketInterrupt() .
SE_INTERNAL_ERROR
The Socket library did something wrong. You should take advantage of whatever developer support to which you have access. They will want a back-trace and other information necessary to duplicate the error.

Up: GEOS SDK TechDocs| Up | Prev: Socket | Next: 2 Simple Example