home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
ipxex3.exe
/
IPXRECV.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-27
|
8KB
|
253 lines
/****************************************************************************
** File: IPXRECV.CPP
**
** Description:
**
** Sample OS/2 application that demonstrates setting up an IPX
** receiver application. This file goes along with IPXSEND.CPP,
** which demonstrates the sending portion of this code. IPXRECV.CPP
** starts three threads to do IPXRECEIVE's, which are blocking calls.
** These threads continue to post receives until the main program
** tells them to terminate or until there is an unrecoverable error.
**
** Disclaimer:
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
** Programmers:
**
** Ini Who Firm
** -------------------------------------------------------------------
** DRS Dan Stratton Novell Developer Support
**
** History:
**
** When Who What
** -------------------------------------------------------------------
** 12-09-94 DRS First code.
** 01-27-95 DRS Modified to work with CSET/++ and Borland
** C++ for OS/2 2.0
*/
#define NWOS2
#define IS32BIT
#if defined (__BORLANDC__)
#define BCPP
void threadCode(void *);
#elif (defined (__IBMC__) || defined(__IBMCPP__))
#define CSET2
#pragma stack16(2048)
void _Export _Optlink threadCode(void *);
#endif
#define INCL_DOSPROCESS
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>
#include <errno.h>
#include <process.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C"{
#endif
#include <nwcalls.h>
#include <ipxcalls.h>
#ifdef __cplusplus
}
#endif
#define IPX_SOCKET 0x4545
#define MAXTHREAD 3
USHORT ipxSocket;
BOOL terminateAllThreads = FALSE;
/* --------------------------------------------------------------------------
threadCode
Notice that we set the transTime to 0. This in effect, tells IPX to check the
LSL buffers and see if there is a waiting packet. If there is, it passes back
the packet. If there isn't, the call will immediately fail and return to this
procedure.
----------------------------------------------------------------------------*/
void threadCode(void *ECB)
{
ULONG timeOut = 0;
int ccode = 0, i = 0;
BOOL killThisThread = FALSE;
do{ /* Notice that we set the timeout to 0. This is basically so that
we can have good response time if we want to shut the threads down,
etc.
*/
ccode = IpxReceive(ipxSocket,timeOut,(IPX_ECB *)ECB);
if ( !ccode )
{ /* These print statements are for demonstration (debugging) purposes
only. You should probably take them out for production.
It is possible to print information somewhat garbled
if you receive large numbers of packets on multiple threads.
Basically, your thread gets timesliced and the next thread starts
printing before the other thread has finished. You could do an
fflush(stdout), but this is just for debugging anyway.
*/
printf("\nPacket received on thread %ld",_threadid);
printf("\nPacket size: %d",NWWordSwap(((UINT16)((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->packetLen)));
printf("\nSending WS = %02X%02X%02X",
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[0],
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[1],
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[2]);
printf("%02X%02X%02X\nPacket contents follow:\n",
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[3],
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[4],
((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->sourceNode[5]);
/*
The NWWordSwap(((UINT16)..... gives you the packetLen field out of the IPX header.
If you subtract the size of the IPX_HEADER, you get the size of the data in the packet
*/
for(i=0;i< NWWordSwap(((UINT16)((IPX_HEADER *)(((IPX_ECB *)ECB)->fragList[0].fragAddress))->packetLen))-sizeof(IPX_HEADER);++i)
{
printf("%c",*((char *)(((IPX_ECB *)ECB)->fragList[1].fragAddress)+i));
}
printf("\n");
}
switch(ccode) /* check for success or error condition */
{
case 0x0000: break;
case 0x9001: break;
case 0x8002: printf("\nError: Bad Packet Received on thread %ld",_threadid);
break;
case 0x8006: printf("\nError: Receive Overflow, buffer too small on thread %ld",_threadid);
break;
case 0x8007: printf("\nError: IPXReceive canceled on thread %ld",_threadid);
break;
case 0x9004: printf("\nError: Socket not open, Terminating thread %ld",_threadid);
killThisThread = TRUE;
break;
default: printf("\nUnknown error during IPXReceive. Terminating thread %ld, ccode %04X",_threadid,ccode);
killThisThread = TRUE;
break;
}
/* Do one IPXRECEIVE, then go to sleep until the next timeslice */
DosSleep(0);
}while (!killThisThread && !terminateAllThreads);
_endthread();
}
int main()
{
IPX_HEADER ipxHeader[MAXTHREAD];
IPX_ECB ipxECB[MAXTHREAD];
char packetBuff[MAXTHREAD][512];
USHORT ccode;
int i;
LONG threadId[MAXTHREAD];
/* open up a socket to receive on */
ipxSocket = IPX_SOCKET;
ccode = IpxOpenSocket(&ipxSocket);
if ( ccode )
{
printf("Error in IpxOpenSocket: %4.4x\n",ccode);
DosExit(EXIT_PROCESS,1);
}
printf("Starting receive threads\n");
/*
Go through a loop to initialize ECB's and start receive threads.
Starts MAXTHREAD threads
*/
for ( i=0; i<MAXTHREAD; ++i )
{
/*
Initialize the Receive ECB
Notice that the IpxHeader is never set to anything, this is filled
in by IPX during the receive
*/
memset((char *)&ipxECB[i],0,sizeof(IPX_ECB));
memset((char *)&ipxHeader[i],0,sizeof(IPX_HEADER));
memset((char *)&packetBuff[i],0,sizeof(packetBuff[i]));
ipxECB[i].fragList[0].fragAddress = &ipxHeader[i];
ipxECB[i].fragList[0].fragSize = sizeof(IPX_HEADER);
ipxECB[i].fragList[1].fragAddress = &packetBuff[i];
ipxECB[i].fragList[1].fragSize = sizeof(packetBuff[i]);
ipxECB[i].fragCount = 2;
ipxECB[i].next = ipxECB[i].prev = NULL;
/* Start MAXTHREAD threads to do receives. Also, _beginthread is
different in CSET, so we need to do a conditional compilation here
*/
#if (defined(__IBMC__) || defined(__IBMCPP__))
if ((threadId[i] = _beginthread(threadCode, NULL, 4096,(void *)&ipxECB[i])) < 0)
#else
if ((threadId[i] = _beginthread(threadCode, 4096, (void *)&ipxECB[i])) < 0)
#endif
{
printf("Unable to create thread %d, errno = %d\n",i,errno);
return errno;
}
printf("Created thread %d, ID = %ld\n",i,threadId[i]);
}
printf("\nPress a key to terminate...\n");
while(!kbhit())
{
DosSleep(0); /* Give up rest of time slice for this thread */
}
printf("\nTerminating all threads");
terminateAllThreads=TRUE; /* Set global var to terminate all threads */
for (i=0;i<MAXTHREAD;++i) /* Wait until all threads have terminated */
{
DosWaitThread((PTID)&threadId[i],DCWW_WAIT);
}
IpxCloseSocket(ipxSocket);
return 0;
}