[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference jamin::pathworks32

Title:Digital PATHWORKS 32
Moderator:SPELNK::curless
Created:Fri Nov 01 1996
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:337
Total number of notes:1612

322.0. "PW32, NT4 : problem with DECNet accept" by EVTAI1::5dhcp239.evt.dec.com::VOUTERS (Philippe 33+ 1 69 87 67 58 DTN 858 6758) Thu May 29 1997 07:02

Hello,

I have problems programming a server task. Using
Pathworks32 DLL on NT4 it loops in the accept (100%
cpu utilization). If I instead use NT4 Winsock DLL,
the accept (DSO_ACCEPTMODE with options ACC_DEFER |
ACC_REUSE) does not loop any longer but the setsockopt
DSO_CONACCEPT is error with error 10042 (if my memory
is correct : WSAENOPROTOOPT). What am I doing wrong ?
Next reply contains the code used.
Note that it worked with Pathworks V4.1B, WNT 3.51.
Waiting for an hint or fixes.
Best regards,
Philippe Vouters (CSC France)
T.RTitleUserPersonal
Name
DateLines
322.1The program for which I do not see what is wrongPRSSOS::VOUTERSPhilippe VOUTERS, Evry (France)Thu May 29 1997 07:47340
/*
EXAMPLE TEMPLATE:

PRODUCT:    PATHWORKS 32

OP/SYS:     Windows NT Version 4.0

SOURCE:     Digital Equipment Corporation


OVERVIEW:
	    This article shows the ability with PATHWORKS for Windows NT
	    to program DECnet communication between an OpenVMS node and
	    a Windows NT node using the Windows NT socket API.

*** CAUTION ***

This sample program has been tested using PathWorks 32 on Windows NT V4.0.
However, we cannot guarantee its effectiveness because of the possibility of
error in transmitting or implementing it. It is meant to be used as a template 
for writing your own program, and may require modification for use on your
system. 


PROGRAM NOTES:

             Compile and link the program below specifying Windows Socket API
	     include files and libraries. Once the executable file is obtained,
	     using the file manager, double click on the executable file. This
	     makes it start without added program arguments. On the OpenVMS
	     session, enter the command $ TYPE WNTnod::"138=" to request
	     a connection to the numbered object 138 created by the program
	     below. You should read on the VMS terminal an hello message with
	     a socket number. Recall the VMS command several times and you
	     should see the socket number can be reused. This proves that
	     the program can be sollicited as many times as wanted without
	     any limits.

PROGRAM:

/*
 *                            COPYRIGHT (C) 1994 BY
 *                      DIGITAL EQUIPMENT CORPORATION, MAYNARD
 *                       MASSACHUSETTS.  ALL RIGHTS RESERVED.
 *
 *    THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
 *    ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION
 *    OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER COPIES
 *    THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
 *    PERSON.  NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
 *
 *    THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
 *    SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
 *
 *    DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
 *    SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
 *
 *    NO RESPONSIBILITY IS ASSUMED FOR THE USE OR RELIABILITY OF SOFTWARE
 *    ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL EQUIPMENT CORPORATION.
 *
 *    SUPPORT FOR THIS SOFTWARE IS NOT COVERED UNDER ANY DIGITAL SOFTWARE
 *    PRODUCT SUPPORT CONTRACT, BUT MAY BE PROVIDED UNDER THE TERMS OF THE
 *    CONSULTING AGREEMENT UNDER WHICH THIS SOFTWARE WAS DEVELOPED.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Winsock API include files follows */
#ifndef _WINSOCKAPI
#include <winsock.h>
#endif
#include <dn.h>

#define BUFSIZ 512
#define DECNET_OBJECT_NUMBER 138


#ifndef FD_SET
/*
struct fd_set_struct {u_char fds_bits[1024/8];};
typedef struct fd_set_struct fd_set;
*/
#define NFDBITS         sizeof(fd_set)/sizeof (u_char)
#define FD_SETSIZE      NFDBITS
#define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
#endif
//---------------------------------------------------------------------------
void cleanup (socket_1)
int socket_1;
{
int	retval;

/*
retval = shutdown (socket_1,2) ;
if (retval == SOCKET_ERROR)
  printf ("shutdown error = %d\n",WSAGetLastError());
*/
retval = closesocket (socket_1) ;
if (retval == SOCKET_ERROR)
  printf ("closesocket error = %d\n",WSAGetLastError()) ;
return;
}
//---------------------------------------------------------------------------
int serve_connection (s)
int s;
{
int r;
int address_len;
fd_set writemask;
unsigned char optval[BUFSIZ];
struct sockaddr_dn socket_address;
int on;
struct accessdata_dn accessdata;
int accesslength;
unsigned int area,node;

printf ("setting SO_REUSEADDR option on socket %d\n", s);
on=1;
if (setsockopt (s,SOL_SOCKET,SO_REUSEADDR,(char *)&on,
				sizeof (on)) == SOCKET_ERROR) {
	printf("setsockopt SO_REUSEADDR error = %d\n",WSAGetLastError());
	cleanup (s);
	return (-1);
}

accesslength = sizeof (accessdata);
printf ("getting DSO_CONACCESS option for socket %d\n",s);
if (getsockopt (s,DNPROTO_NSP,DSO_CONACCESS,
		(char *)&accessdata,&accesslength) == SOCKET_ERROR) {
	printf ("setsockopt DSO_CONACCEPT error %d\n",WSAGetLastError());
	cleanup (s);
	return (-1);
	}
printf ("Received connection from account %.*s, user %.*s\n",
		accessdata.acc_accl,accessdata.acc_acc,
		accessdata.acc_userl,accessdata.acc_user);

printf ("setting DSO_CONACCEPT option on socket %d\n",s);
if (setsockopt (s,DNPROTO_NSP,DSO_CONACCEPT,(char *)&on,
			sizeof(on)) == SOCKET_ERROR) {
	printf ("setsockopt DSO_CONACCEPT error %d\n",WSAGetLastError());
	cleanup (s);
	return (-1);
	}

printf ("obtaining partner address\n");

address_len = sizeof(socket_address);

if (getpeername (s,(struct sockaddr *)&socket_address,
					&address_len)
							== SOCKET_ERROR) {
    printf ("Socket getpeername error %d\n",WSAGetLastError());
    cleanup (s);
    return (-1);
    }
area = ((socket_address.sdn_add.a_addr[0]+ 
			socket_address.sdn_add.a_addr[1]*256)   & 0xfc00)>> 10;
node = (socket_address.sdn_add.a_addr[0] +
		    socket_address.sdn_add.a_addr[1]*256) & 0x3ff;
printf("Connection from node %1d.%1d\n", area, node);

FD_ZERO(&writemask);
FD_SET(s,&writemask);

/* Is the socket s writeable ? If yes, the bit at position s in writemask */
/* will be set to one enbling us to send data to the VMS node		  */
if ((r=select (s+1,NULL,&writemask,NULL,NULL)) == SOCKET_ERROR) {
    printf ("Socket select error %d\n",WSAGetLastError());
    cleanup (s);
    return (-1);
    }

/* Wait for remote node to setup the link before sending data */
/* sleep (1); */
Sleep (1000);

if (FD_ISSET (s,&writemask)) {
    sprintf (optval,"Hello From Decnet Windows NT, socket number %d",s);
    if (send (s,optval,strlen(optval),0) == SOCKET_ERROR){
        printf ("Send error = %d\n",WSAGetLastError());
        cleanup (s) ;
        return (-1);
	}

    printf ("sent to remote node %s\n",optval);
    }
else
    printf ("cannot write socket %d\n", s);
cleanup (s) ;
return (0);
}
//---------------------------------------------------------------------------
int main (int argc, char **argv) {

int s,lsock, address_len;
struct sockaddr_dn socket_address,dyn_sock_address;
struct sockaddr_dn *this_socket = (struct sockaddr_dn *)&socket_address;
FILE *fp;
WORD wVersionRequested;
WSADATA wsaData;
char *cp,*cp1;
struct {int on;int option;} opt;

/*
 * Open a log file with the same filename than the executable but the extension
 * ".log"
*/
cp = malloc (strlen(argv[0])+10);
strcpy (cp,argv[0]);
cp1 = strchr(cp,'.');
if (cp1 != NULL){
     *cp1 = '\0';
     strcat (cp,".log");
     }
else strcat (cp,".log");
fp = fopen (cp, "a");

/* Start up the Windows socket API DLL */

wVersionRequested = MAKEWORD(1,1);
if(WSAStartup(wVersionRequested,&wsaData)!=0){
   fprintf (fp,"WSAStartup failed\n");
   fclose (fp);
   exit (1);
}

if ((LOBYTE(wsaData.wVersion) != 1)	||
	(HIBYTE(wsaData.wVersion) != 1)) {
	fprintf (fp,"WSAStartup bad version %d,%d\n",
		LOBYTE(wsaData.wVersion),
		HIBYTE(wsaData.wVersion));
	fclose (fp);
	WSACleanup();
	exit(1);
}

/* Create a DECnet socket. */

if ((lsock = socket ( AF_DECnet,SOCK_SEQPACKET,
			DNPROTO_NSP)) == INVALID_SOCKET) {
     printf ("socket lsock error = %d\n",WSAGetLastError());
	fclose(fp);
	WSACleanup();
	exit (1);
        }
printf ("Created socket lsock %d\n", lsock);


/* Now bind lsock to a DECnet object number */

memset (&socket_address, 0, sizeof (socket_address));

this_socket->sdn_family = AF_DECnet ;
if (argc > 1) 
    this_socket->sdn_objnum = atoi(argv[1]);
else this_socket->sdn_objnum = DECNET_OBJECT_NUMBER ;
if (argc > 1)
    sprintf (this_socket->sdn_objname,"Test_%s",argv[1]);
else strcpy (this_socket->sdn_objname,"test_138");
this_socket->sdn_objnamel = strlen (this_socket->sdn_objname);

if ( bind (lsock,(struct sockaddr *)&socket_address,
	        sizeof (socket_address))== SOCKET_ERROR) {
     printf ("bind lsock error = %d\n",WSAGetLastError());
	 WSACleanup();
     fclose(fp);
	 exit (2);
}
printf ("socket lsock %d binded to an AF_DECNET named structure\n", lsock);

printf ("setting DSO_ACCEPTMODE with ACC_DEFER | ACC_REUSE option on socket %d\n", s);
opt.on = 1;
opt.option = ACC_DEFER | ACC_REUSE ;
if (setsockopt (lsock,DNPROTO_NSP,DSO_ACCEPTMODE,(char *)&opt,
				sizeof (opt)) == SOCKET_ERROR) {
	printf("setsockopt DSO_ACCEPTMODE | ACC_DEFER error = %d\n",WSAGetLastError());
	cleanup (lsock);
	fclose (fp);
	exit (5);
}

/* Wait for connections requests (listen) and redirect the connection to a
 * dynamic socket s (accept).
*/
for (;;){
	printf ("listening connection on lsock %d\n", lsock);
	if (listen (lsock, 5)== SOCKET_ERROR) {
		printf ("listen error = %d",WSAGetLastError()) ;
		cleanup (lsock) ;
		fclose(fp);
		exit (3);
	}
	printf ("Accepting connection on socket lsock %d\n", lsock);
	address_len = sizeof (struct sockaddr_dn);
    s = accept (lsock, (struct sockaddr *)&dyn_sock_address, &address_len);
 	printf ("Connection accepted on socket %d\n",s);
	if (s == INVALID_SOCKET){
		printf ("accept error %d",WSAGetLastError()) ;
		cleanup (s) ;
		cleanup (lsock) ;
		fclose(fp);
		exit (4);
	}

    /* Now we can create a thread that will serve the connection on socket s
     * this will be simulated by a call to a subroutine.
    */

    printf ("servicing the connection on socket %d\n", s);
    if (serve_connection (s) < 0) break;
 } /* end for(;;) */
 WSACleanup();
 printf ("Closing socket %d\n", lsock);
 cleanup(fp,lsock);
 fclose (fp); 

exit (EXIT_SUCCESS); 
return (1);
}
/*
\
\
\ CONTRIBUTORS:
\
\      Technical:
\           Philippe Vouters (161304)
\           Pierre Quenard (131421)
\
\      Editorial:
\           {edit_contributor_name} ({badge})
\           {edit_contributor_name} ({badge})
\! Please do not remove lines below this point - for administration purposes
\! ---------------------------------------------------------------------------
\\ TYPE=TECH_TIPS TYPE=EXAMPLE
*/
322.2will winsock 2 workJAMIN::KROBINSONThu May 29 1997 12:286
You may want to try using winsock 2 DECnet.  It is now the standard for sockets on NT 4.0.  Look on your PW32
kit in i386\pwsdk\samples\winsock2\samples.txt.  Also look in dloopst and dloops2t for samples that listen on a
DECnet socket and accept() connections.

Ken Robinson
Winsock 2 DECnet