GEOS SDK TechDocs|
|
1 Introduction |
3 Addresses The sample application Appl/SDK_C/Talk provides an example of a simple application using the Socket library.
To understand how the program works, you should, of course, look at its source code. The following is a high-level overview of what the Talk example illustrates: a simple client-server connection in which the server awaits connections, the client connects, and then the two exchange data. Note: this application assumes that the host device (the client) has already connected to the server. Remote connections are usually made through PPP or Point-to-Point Protocol. See
SocketOpenDomainMedium()
discussed in Hardware Ports.
The example performs the following steps:
SocketSetIntSocketOption()
to change its owning thread.)char recvBuf[16];
AccessPointControl
object prompts the user to choose an ISP, and a call to
SocketOpenDomainMedium()
opens a PPP connection to that ISP.
SocketGetAddressController()
returns the controller class' pointer;
ObjInstantiate()
creates an object of the class.ctrlClass = SocketGetAddressController(theAddress.SA_domain));
ctrlOb =
ObjInstantiate(
HandleOf(GeodeGetOptrNS(@AddressDialog)),
ctrlClass);
@call ctrlOb::MSG_SOCKET_ADDRESS_CONTROL_SET_ACTION( ConstructOptr(0,TO_PROCESS), MSG_CTP_VALID);
@call
GeodeGetOptrNS(@AddressDialog)::MSG_GEN_ADD_CHILD(
ctrlOb, CCO_FIRST);
@call ctrlOb::MSG_GEN_SET_USABLE(VUM_NOW);
When the user enters an address, the following code is called. It gets the selected address from the address controller and packages it up into a form the Socket library can use.
MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES
returns a chunk with raw address data based on the address entered by the user.
SocketResolve()
reduces this raw address data to a primitive form that can be used for making connections.
adArray = @call ctrlOb::MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES();
address1 = ChunkArrayElementToPtrHandles( HandleOf(ctrlOb), adArray, 0,0);
theAddress.SA_addressSize =
SocketResolve(
theAddress.SA_domain, (byte *)&address1[1],
address1->SACA_opaqueSize, addressBuffer,
MAX_ADDRESS_SIZE);
LMemFreeHandles(HandleOf(ctrlOb), adArray);
dataSocket = SocketCreate(SDT_STREAM);
SocketConnect( dataSocket, (SocketAddress *) &theAddress, SOCKET_NO_TIMEOUT);
There are two "sockets" created on this, the server side of the connection. The first socket is bound to a particular port, and "listens" for incoming connections. It is possible to accept more than one connection over the listening socket--each accepted connection is represented by another socket to represent this side of the new particular connection.
listenSocket = SocketCreate(SDT_STREAM);
SocketBind(listenSocket, theAddress.SA_port, 0);
SocketListen(listenSocket, 5);
dataSocket = SocketAccept( listenSocket, SOCKET_NO_TIMEOUT);
textBlock = @call GeodeGetOptrNS(@InText):: MSG_VIS_TEXT_GET_ALL_BLOCK(NullHandle);
textPtr = MemLock(textBlock);
textSize = LocalStringSize(textPtr);
SocketSend( dataSocket, textPtr, textSize, 0, (SocketAddress *)0);
MemFree(textBlock);
while ((
datasize = SocketRecv(
dataSocket, recvBuf, sizeof recvBuf,
SOCKET_NO_TIMEOUT, 0, (SocketAddress *)0))
!= 0)
{ @call
GeodeGetOptrNS(@OutText)::MSG_VIS_TEXT_APPEND_PTR(
recvBuf, datasize); }
SocketCloseSend()
routine partially shuts down the socket so that it can receive data, but cannot send it; also, the routine sends a signal to the other side that the connection is closing.if (listenSocket) {
SocketClose(listenSocket);
listenSocket = 0; }
SocketCloseSend(dataSocket);
SocketRecv()
detects an error, it sets the thread error value, which may be retrieved via
ThreadGetError()
.) If the connection has closed, then Talk closes the sockets on this side of the connection.if (ThreadGetError() == SE_CONNECTION_CLOSED) {
if (listenSocket) {
SocketClose(listenSocket);
listenSocket = 0; }
SocketClose(dataSocket); }
GEOS SDK TechDocs|
|
1 Introduction |
3 Addresses