NetStreams Using NetStreams

Using NetStreams

In this page the basic techniques are explained. Reviewing the samples packaged with the DLL you can see them in action.

The library has one "root" object which is helper and also provider for a general functionality not applicable for any other particular object in the library. Its name is NSMain. It has several methods that create directly the other library objects allowing you to avoid using CreateObject or other ActiveX creation facilities once you have one NSMain created by your code. This makes the code a bit more clear and also ensures all the objects are created in the same COM apartment which may improve the performance in many scenarios. Another important function of this object is to initialize the WinSock library - while it is "alive" the WinSock is initialized. You can think the NSMain represents tha WinSock session. So the first step always will be creating one such object and then asking it to provide whatever other objects you may need for our work.

Although some applications may need only some lookup features, most applications of NetStreams will include data transfer. We can describe this as a set of several generalized steps.

A typical client connection:

  1. The application finds the service provider.
    In this step for instance the application may need to resolve a DNS name or perform an IRDA devices lookup. After doing so it will have a ready-to-use address of the desired service provider or it will "know" that it cannot be found. Depending on the specifics the application may need to create and initialize a SocketStream object at certain point of the process. If it does not require this the application creates/inits a SocketStream object ready to be connected to the discovered address.
  2. Connects to it
    In this step the application uses the address from the first step to connect the already created SocketStream object to the server. This may fail if the server is unreachable, down or otherwise inaccessible at this very moment. If the connection is successful the application creates a SFStream object (from newObejcts ActiveX Pack1) and sets the connected socket to it. Alternatively applications written in C++ (or another language with native COM interfaces support) can query the connected SocketStream object for IStream interface.
  3. Transfers data
    Now the applications performs read and write operations over the SFStream object (or directly through the IStream interface - C++ apps. only). Depending on the server protocol (for example HTTP, POP3, SMTP, IMAP and so on) the application may use binary or text read/write methods of SFStream in different order and with different options - as appropriate for the application and protocol requirements.
  4. Closes the connection
    When the work is done it is time to close the SocketStream object and thus close the connection (it can be already closed by the server depending on the protocol used - for example HTTP behaves this way if no "keep-alive" is requested). Further the application does whatever clean up work it needs to do.

A typical server:

  1. Determine the address on which the services will be provided.
    This may be needed or may be not - depending on the server implementation and mostly depending on the parameters/configuration it accepts (i.e. it is a matter of design).
  2. Server binds to the address(es).
    The application creates a SocketStream object, initializes it for the address family and protocol on which it will serve. Then uses the SocketStream.Bind to bind the socket to the address. Depending on the protocol the application may need to specify service name or a port number in the address for binding. Some protocols (IP for example) allow the system to choose free port or some sort of service id and the application is able to learn it by examining the socket's address after successful binding (SocketStream.SocketAddress property).
  3. Application begins to listen and accept the incoming connections.
    In this step the application usually calls the Listen method to instruct WinSock listen for incoming connections and then uses the Accept method to obtain them as they occur. Depending on the server application's structure it may use threads or process all the connections in the main thread. The latter method most often will involve usage of non-blocking mode. Non-blocking mode is a little harder to implement compared to blocking mode where the code needed is really simple, but sometimes for servers servicing small number of clients it may be more efficient than implementing threads.
    The SocketStream.Accept method returns a new SocketStream object which represents the received connection with a client. The application uses it just like on the client side after the point where it is connected.
  4. Servicing the connection.
    As the application obtains the new SocketStream obejct from the Accept method it needs to create SFStream and set the SocketStream to it (or alternatively C++ apps. can query it for IStream interface and use it directly). Read/write operations are done like in a client application and as the protocol implemented requires.
  5. Finish the work with a particular connection.
    After finishing the conversation with a client the server application disconnects the socket and "forgets" it. If a thread per-client is used then the thread may complete, if the work is done in the main thread then perhaps the application keeps the currently connected/serviced SocketStream objects in some kind of pool (array, collection etc.). Thus the application removes the SocketStream object from that pool.
  6. Server shutdown.
    The server application closes the listening socket that was bound to an address in step 2 and releases all the resources involved in servicing clients.
newObjects Copyright 2001-2006 newObjects [ ]