GEOS SDK TechDocs|
|
4 Making a Connection |
6 Loading on Connection SocketBind(), SocketBindInDomain(), SocketListen(), SocketAccept()
There's a bit of work involved in setting up a program to receive connections from other sockets. The program must create a socket and associate it with a port. If there is to be a sequenced-packet or stream delivery connection, then the program needs to do some more work to listen for and accept these connections.
If a program creates a socket that accepts connections, the program should probably spawn a separate thread for each accepted connection. If this is not practical, then see
SocketCheckReady()
for a way to monitor several sockets with a single thread.
Call
SocketCreate()
to create a socket for this side of the connection. If the socket is to receive datagram packets, then it must be of type datagram. If the other socket in the connection will be a sequenced packet or stream delivery type, then the socket accepting the connection must be either sequenced packet or stream delivery type; however, the two sockets need not be of the same type.
(If you follow the multi-threaded approach, be aware that when the Socket's owning thread exits, it frees the Socket. To allow a Socket to survive the exit of its thread, use
SocketSetIntSocketOption()
to change its owning thread.)
The other side of the connection attempts to hook up to a port number on this side of the connection. If a socket is to intercept connections to a certain port, it must somehow associate itself with that port. Use the
SocketBind()
or
SocketBindInDomain()
routines to associate a socket with a port number.
SocketBind()
associates the socket with a port number.
SocketBindInDomain()
associates the socket with a port number but only within a specific domain.
For any given domain, normally only one socket on the machine may be bound to any port number. Thus, if you call
SocketBindInDomain()
to bind socket A to port 3 in the TCP/IP domain, then:
SocketBindInDomain()
to bind socket B to port 3 in the IRLAP domain, but
SocketBindInDomain()
to bind socket C to port 3 in the TCP/IP domain, and
SocketBind()
to bind socket D to port 3.There are some ways around this restriction:
SocketBind()
or
SocketBindInDomain()
to re-use some port that another socket has bound, then pass the SBF_REUSE_PORT flag. Otherwise, be prepared to receive SE_PORT_IN_USE or SE_BIND_CONFLICT. Even the SBF_REUSE_PORT flag won't allow you to use both
SocketBind()
and
SocketBindInDomain()
on a single port. E.g., in the example above, you could use
SocketBindInDomain()
with SBF_REUSE_PORT to bind socket C to port 3 in the TCP/IP domain, but you could not use
SocketBind()
with SBF_REUSE_PORT to bind socket D to port 3. You may not use SBF_REUSE_PORT with datagram-based sockets.Always check for bind conflicts. Bind conflicts may occur even though a program is well-behaved: other programs may have bound ports to a socket. For reasons described in Loading on Connection, sometimes the Socket library itself may monitor a port.
When setting up a sequenced packet or stream delivery connection, a bit more set-up work is necessary. These delivery types require a "connection."
To listen for incoming sequenced packet or stream connections, call
SocketListen()
. The socket must be bound to a port before it can listen. To allow more than one connection through the port, specify the maximum number of connections as an argument to
SocketListen()
. The
SocketListen()
routine causes a socket to listen for incoming connections. If another socket is listening at the port,
SocketListen()
returns SE_PORT_ALREADY_LISTENING.
To make a socket wait for and accept a connection, call
SocketAccept()
. The socket must be listening for connections (processed by
SocketListen()
). Because the thread blocks until a connection is made or
SocketAccept()
times out, programs normally don't call this routine in their main execution thread. As in the Appl/SDK_C/Talk sample application, a separate thread handles accepting a connection and receiving data from the connection.
If a connection is made,
SocketAccept()
returns a
Socket
used to represent the connection. Do not confuse this connected socket with the listening socket. You might be able to accept more connections from the listening socket.
If
SocketAccept()
returns SE_LISTEN_QUEUE_EMPTY, then there were no connections waiting to be accepted.
GEOS SDK TechDocs|
|
4 Making a Connection |
6 Loading on Connection