Socket: 1
Introduction
|
GEOS SDK TechDocs|
|
Socket |
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.
|
GEOS SDK TechDocs|
|
Socket |
2 Simple Example