Get SupportDownload SoftwareGo ShoppingContact Us
Log-In Log-Out
 














 
Last Updated
 
Course Home Download NLM.exe 96KB

Coding Example Two

INTERNET ACCESS

The Internet has an almost endless amount of data available. Let's now look at an example that accesses the Internet in an NLM.

You should have a CodeWarrior IDE icon on your desktop after installing CodeWarrior. You should have installed the NetWare CD for CodeWarrior to develop NLMs. NLM.EXE should be installed. Click on the CodeWarrior IDE icon to start CodeWarrior.

SERVER SOCKET APPLICATION

To use your first application, click your mouse on the "Open Recent" section. Select "ServSock.mcp".

Open recent files dialog

SOCKET COMMUNICATION

By selecting ServSock.mcp you should be ready for examining the code in Adduser.c

Open Adduser.c again by double-clicking on the icon in the IDE project.

You should see the following:

/***************************************************************************

 Copyright (c) 1998 Novell, Inc. All Rights Reserved.

 THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
 USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
 ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
 PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
 ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS
 PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
 DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S
 PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S
 CUSTOMERS WITH RESPECT TO THIS CODE.
****************************************************************************/

/*
 * Example server for NetWare TCP/IP Socket API.
 * 
 * This example server accepts a connection on port 2001, 
 * and calls a function to handle the connection (for purposes 
 * of simplicity, there is no multithreading, although normally this 
 * implementation would allow multiple connections via daughter threads)  
 *
 * The function reads data from the socket and echoes it to the server 
 * console screen and sends it back to the client until the client closes. 
 * Then it closes the connection * and returns.  The main function is never 
 * ended, so an unload signal  function must close the listen socket.
 * 
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <io.h>
#include <process.h>
#include <signal.h>

// Functions
int read_connection();
void unloadProcedure( int );
void exit_error( const char * );

// Globals
SKT             listen_skt = 0,
	 	 connect_skt = 0;
int NLM_mainThreadGroupID;   /* clib context handle  */
struct sockaddr_in server_sockaddr;
struct sockaddr_in client_sockaddr;

main()
{
	 int             rc,
	                 arg;
	 
	 /* Save off main thread group ID for unload process */
	 NLM_mainThreadGroupID = GetThreadGroupID();

	 /* Register the unload process for asynchronous user unload. */
	 signal( SIGTERM, unloadProcedure );

	 /* Create a socket */
	 listen_skt = socket( PF_INET, SOCK_STREAM, 0 );
	 if ( listen_skt == -1 ) exit_error( "socket" );
	 
	 server_sockaddr.sin_family = AF_INET;
	 server_sockaddr.sin_port = htons( 2001 );

	 /* bind socket to port */
	 rc = bind( listen_skt, ( struct sockaddr * ) &server_sockaddr, sizeof( 
server_sockaddr ) );
	 if( rc == -1 ) exit_error( "bind" );

	 /* Start listening for client connections */
	 rc = listen( listen_skt, 5 );
	 if( rc == -1 ) exit_error( "listen" );

	 for ( ;; ) 
	 {
	 	 printf( "\n\nTCPIP Echo Server Waiting...\n\n" );
	 	 arg = sizeof ( client_sockaddr );

	 	 /* accept returns the new socket so that we can continue */
	 	 /* listening on the original socket                      */
	 	 connect_skt = accept( listen_skt, (struct sockaddr *) &client_sockaddr, &arg );
	 	 if( connect_skt == -1 ) exit_error( "accept" );

	 	 /* Call function to handle new connection.  Ideally a new  */
	 	 /* thread would be spawned so that multiple processes can  */
	 	 /* operate simultaneously.  For simplicity, this is a      */
	 	 /* single-process server                                   */
	 	 rc = read_connection();
	 	 if( rc == 0 )
	 	 {
	 	 	 printf( "\nError, server going down" );
	 	 	 exit( 1 );
	 	 }
	 }
}

int read_connection()
{
	 int             rc;
	 char            iochar;
	 
	 /* Read a char, print it out, write it back */
	 while( rc = recv( connect_skt, &iochar, sizeof ( iochar ), 0 ) ) 
	 {

	 	 if ( rc == -1 ) 
	 	 {
	 	 	 exit_error( "recv" );
	 	 }
	 	 putchar( iochar );

	 	 rc = send( connect_skt, &iochar, sizeof( iochar ), 0 );
	 	 if ( rc == -1 ) 
	 	 {
	 	 	 perror( "send" );
	 	 	 raise( SIGTERM );	 	 
	 	 	 exit( 1 );
	 	 }
	 }
	 close( connect_skt );
	 connect_skt = 0;
	 return( 1 );
}

void unloadProcedure( int i )
{
	 int 	 	 handlerThreadGroupID;

	 /*  Store this thread's context and setup clib context */
	 handlerThreadGroupID = GetThreadGroupID();
	 SetThreadGroupID( NLM_mainThreadGroupID );

	 /* Release socket resources */
	 if( connect_skt ) 
	 {
	 	 printf( "Closing connect socket\n" );
	 	 close( connect_skt );
	 	 connect_skt = 0;
	 }
	 if( listen_skt ) 
	 {
	 	 printf( "Closing listen socket\n" );	 	 
	 	 close( listen_skt );
	 	 listen_skt = 0;
	 }
	 /* Restore Context */
	 SetThreadGroupID( handlerThreadGroupID );
}

void exit_error( const char * str )
{
	 perror( str );
	 raise( SIGTERM );
	 exit( 1 );
}

I will now explain what this code does.

Build the NLM by pressing the F7 key. You could also click "Project" and then "Make" to build the project.

Now copy the file ServSock.nlm from the hard drive on the client to the \system directory on the NetWare server. You may have to look for the ServSock.nlm file to complete the copy.

This information is shown on the server screen when the NLM executes.

Click Save

Bring up the code Adduser.c

You will notice that AddUser.c is not the code that adds a user to NDS. This code comes from the download area on DeveloperNet. I have copied that code over the Adduser.c file to demonstrate that the code will build and run from the example code found on DeveloperNet.

Lets examine the code:

#include <sys/socket.h>
#include <netinet/in.h>

These two header files contain the APIs that are needed to access the Internet.

listen_skt = socket( PF_INET, SOCK_STREAM, 0 );

Socket programming requires a program to listen on one port and then communicate on another port. That way the listen port is always available for another connection. You should notice that the socket is in stream mode and not block mode. The program sends one character of information in each packet.

server_sockaddr.sin_port = htons( 2001 );

We are going to access on port 2001. To communicate we need to access on port 2001 on our client. To use a Socket we must know the IP address of the server socket and the port number. Much like a telephone you must have the complete telephone number to communicate with that telephone. Two points to think about. First, this is an example program and you should not hard code a port in an NLM. Your NLM should have several numbers that it can use if a given port is unavailable. This requires a little more effort on your part, but resolves many issues on a customer's server.

Second, you should use port numbers greater then 7000. Lower numbers are available but are often in use by other programs. I like to use numbers like 9797. This avoids others numbers that increment from a hundreds number, like 7000,7001, 7002 etc.

rc = bind( listen_skt, ( struct sockaddr * ) &server_sockaddr, sizeof( server_sockaddr ) );

You need to bind the socket and verify that you are able to access that port number. A bind will hold that port number for your program when successful.

printf( "\n\nTCPIP Echo Server Waiting...\n\n" );
/* accept returns the new socket so that we can continue */
/* listening on the original socket                      */
connect_skt = accept( listen_skt, (struct sockaddr *) 

The program prints the message "TCPIP Echo Server Waiting" and executes the accept command. The server will display this message and the NLM will wait for a client to connect.

This NLM communicates with TCPIP.NLM provided with NetWare 5 and NetWare 4. TCPIP.NLM must be loaded for this program to communicate.

while( rc = recv( connect_skt, &iochar, sizeof ( iochar ), 0 ) ) 
{
putchar( iochar );
rc = send( connect_skt, &iochar, sizeof( iochar ), 0 );

When we get a valid connection, we will receive a packet of information. Then, print it to the server screen and then return the information back to the client. Understand that we are sending many packets with one character at a time. To send blocks of data we need to change the socket command. This is only an example program. It might be useful for a game programmer to use to send information quickly, but a LanAnalyzer trace would show intense traffic if a large number of users were using this socket type.

BUILDING SERVSOCK.NLM

Click on the Target setting ICON in the project screen.

The Target icon looks like this:

Target Icon

Click on NLM Target.

You should see the following:

NLM target settings

1. Name this NLM, "ServSock.NLM".

2. Rename the output file to be "ServSock.NLM".

3. Change the Initial screen to be "TCP/IP Server Socket".

4. Change the description to be "TCP/IP Server Socket Example".

5. Click on the Save button. Click on the "x" to close the window.

6. Next build the program by pressing the F7 key.

7. Now copy the ServSock.NLM executable to F:\system for the server to use.

On the server command line, type ServSock to start the program. Use <ALT><ESC> to change screens on the server to the "TCPIP Echo Server Waiting..." message. The client will now use Telnet to attach to the IP address and port number. This socket will transmit and receive information using the TCP/IP protocol.

On the client, type "telnet" in a DOS prompt. Get the IP address of the server by typing "config" on the server console. Enter the IP address in the Host Name box in the telnet program. Change Port to 2001 and Term Type as vt100. You should now see what you type in telnet on the server console.

Telnet dialogs

Type a few lines in Telnet. You will notice that the server receives the information as programmed. Close Telnet and Unload ServSock.NLM.

From these examples, you now know that an NLM can communicate to any program on the Internet. All of these different worlds are able to communicate to NDS through an NLM.


Last updated on:

Course Home Download NLM.exe 96KB