├── dsample ├── client.c └── server.c ├── include ├── netdb.h ├── netinet │ └── in.h ├── sock_err.h ├── sockdefs.h ├── sys │ └── socket.h ├── wsockdef.h └── wsockets.h ├── lib ├── dos_sock.lib ├── os2_sock.lib ├── wsockets.dll └── wsockets.lib ├── netprog └── sockets.exe ├── orig └── mstcpsdk.rar ├── readme.txt └── wsample ├── clnt_srv ├── client.c ├── client.def ├── client.exe ├── client.h ├── client.mak ├── client.rc ├── readme.txt ├── server.c ├── server.def ├── server.exe ├── server.h ├── server.mak └── server.rc └── udp ├── readme ├── winudp.c ├── winudp.def ├── winudp.exe ├── winudp.h ├── winudp.mak └── winudp.rc /dsample/client.c: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define BUFFER_SIZE 1000 14 | #define LINE_LEN 70 15 | 16 | char sendbuf[BUFFER_SIZE]; 17 | char recvbuf[BUFFER_SIZE]; 18 | struct sockaddr_in server_addr, client_addr; 19 | 20 | 21 | int sleep( seconds ) 22 | int seconds; 23 | { 24 | long start_seconds, current_seconds, end_seconds; 25 | 26 | time( &start_seconds ); 27 | end_seconds = start_seconds + (long) seconds; 28 | 29 | do { 30 | time( ¤t_seconds ); 31 | } while ( current_seconds < end_seconds ); 32 | 33 | return( 0 ); 34 | } 35 | 36 | 37 | /* 38 | ** This program acts as a sockets IPC client. It will attempt to connect to 39 | ** a remote server node, send, and then receive data. 40 | */ 41 | 42 | int errno; 43 | 44 | main( argc, argv ) 45 | int argc; 46 | char *argv[]; 47 | { 48 | int rc, i, len, total, size, sd, seconds; 49 | 50 | if ( argc < 5 ) { 51 | printf( "Usage: %s \n", argv[0] ); 52 | exit( 1 ); 53 | } 54 | 55 | size = atoi( argv[3] ); 56 | 57 | 58 | /* 59 | ** Create a local endpoint for communication. 60 | */ 61 | 62 | sd = socket( AF_INET, SOCK_STREAM, 0 ); 63 | if ( sd < 0 ) { 64 | printf( "Error: socket() call failed w/rc=%d, errno=%d\n", sd, errno ); 65 | exit( 1 ); 66 | } 67 | printf( "socket() returned %d\n", sd ); 68 | 69 | 70 | /* 71 | ** Fill in a socket address structure with the necessary information 72 | ** about the remote server node (remote node IP address and port for 73 | ** incoming connections) and attempt to connect to the server. This connect 74 | ** call will block until the remote server has accepted the connection or 75 | ** the connection request times out. 76 | */ 77 | 78 | server_addr.sin_family = AF_INET; 79 | server_addr.sin_port = htons( atoi( argv[2] ) ); 80 | server_addr.sin_addr.s_addr = inet_addr( argv[1] ); 81 | 82 | rc = connect( sd, (struct sockaddr *) &server_addr, sizeof(server_addr) ); 83 | if ( rc < 0 ) { 84 | printf( "Error: connect() call failed w/errno=%d\n", errno ); 85 | close_socket( sd ); 86 | exit( 1 ); 87 | } 88 | printf( "Established connection with 0x%lx\n", server_addr.sin_addr ); 89 | seconds = atoi( argv[4] ); 90 | printf( "Waiting %d seconds before sending data...\n", seconds ); 91 | sleep( seconds ); 92 | 93 | /* 94 | ** Send the number of bytes specified on the command line to the server. 95 | */ 96 | 97 | for (i=0; i 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define BUFFER_SIZE 1000 12 | 13 | char sendbuf[BUFFER_SIZE]; 14 | char recvbuf[BUFFER_SIZE]; 15 | 16 | struct sockaddr_in server_addr, client_addr; 17 | 18 | int sleep( seconds ) 19 | int seconds; 20 | { 21 | long start_seconds, current_seconds, end_seconds; 22 | 23 | time( &start_seconds ); 24 | end_seconds = start_seconds + (long) seconds; 25 | 26 | do { 27 | time( ¤t_seconds ); 28 | } while ( current_seconds < end_seconds ); 29 | return( 0 ); 30 | } 31 | 32 | 33 | /* 34 | ** This short program will act as a network 'server' and will accept a 35 | ** single incoming connection. After the connection is established, data 36 | ** will be received and then transmitted, and the server terminates 37 | */ 38 | 39 | int errno; 40 | 41 | 42 | main( argc, argv ) 43 | int argc; 44 | char *argv[]; 45 | { 46 | int rc, i, len, total, listen_sd, acc_sd; 47 | unsigned int size; 48 | 49 | 50 | if ( argc < 3 ) { 51 | printf( "Usage: %s \n", argv[0] ); 52 | exit( 1 ); 53 | } 54 | 55 | size = atoi( argv[2] ); 56 | 57 | 58 | /* 59 | ** Create a socket locally to serve as a communication endpoint. 60 | */ 61 | 62 | listen_sd = socket( AF_INET, SOCK_STREAM, 0 ); 63 | if ( listen_sd < 0 ) { 64 | printf( "Error: socket() call failed with errno=%d\n", errno ); 65 | exit( 1 ); 66 | } 67 | printf( "socket() returned %d\n", listen_sd ); 68 | 69 | 70 | /* 71 | ** 'Bind' the newly created socket to a wildcard local IP address and 72 | ** the local TCP port specified on the command line 73 | */ 74 | 75 | server_addr.sin_family = AF_INET; 76 | server_addr.sin_port = htons( atoi( argv[1] ) ); 77 | server_addr.sin_addr.s_addr = INADDR_ANY; 78 | 79 | rc = bind( listen_sd, (struct sockaddr *) &server_addr, 80 | sizeof( server_addr ) ); 81 | if ( rc < 0 ) { 82 | printf( "Error: bind() call failed w/errno=%d\n", errno ); 83 | close_socket( listen_sd ); 84 | exit( 1 ); 85 | } 86 | printf( "bind() call returned %d\n", rc ); 87 | 88 | 89 | /* 90 | ** Create a queue of length one to hold incoming connection requests. 91 | */ 92 | 93 | printf( "server will listen on port %d\n", ntohs( server_addr.sin_port ) ); 94 | rc = listen( listen_sd, 1 ); 95 | if ( rc < 0 ) { 96 | printf( "Error: listen() call failed w/errno=%d\n", errno ); 97 | close_socket( listen_sd ); 98 | exit( 1 ); 99 | } 100 | printf( "listen() call returned %d\n", rc ); 101 | 102 | 103 | /* 104 | ** Call accept(), which will block until an incoming connection is 105 | ** established on the listening socket. Accept() then returns the socket 106 | ** descriptor of the new socket and will also fill in the 'client_addr' 107 | ** socket address structure with the remote IP address and port. 108 | */ 109 | 110 | len = sizeof( struct sockaddr_in ); 111 | printf( "blocking on accept() waiting for an incoming connection...\n" ); 112 | acc_sd = accept( listen_sd, (struct sockaddr *) &client_addr, &len ); 113 | if ( acc_sd < 0 ) { 114 | printf( "Error: accept() call failed w/errno=%d\n", errno ); 115 | close_socket( listen_sd ); 116 | exit( 1 ); 117 | } 118 | printf( "Established connection with 0x%lx\n", client_addr.sin_addr ); 119 | 120 | 121 | /* 122 | ** The connection is now established. 123 | ** 124 | ** We will receive all of the data sent by the remote node before sending 125 | ** data out. There is one caveat, however. The recv() call is defined 126 | ** such that it returns as soon as ANY data is available rather than 127 | ** waiting until all 'size' bytes of data havebeen read. Therefore, we 128 | ** must loop on the recv() call until all data has been received. 129 | */ 130 | 131 | total = 0; 132 | printf( "Now attempting to receive data...\n" ); 133 | do { 134 | len = recv( acc_sd, &recvbuf[total], size-total, 0 ); 135 | if ( len < 0 ) { 136 | printf( "Error: recv() call failed w/errno=%d\n", errno ); 137 | close_socket( listen_sd ); 138 | close_socket( acc_sd ); 139 | exit( 1 ); 140 | } 141 | printf( "recv() returned %d bytes\n", len ); 142 | total += len; 143 | } while ( total < size ); 144 | 145 | 146 | /* 147 | ** Echo the received data back to the remote node. 148 | */ 149 | 150 | len = send( acc_sd, recvbuf, size, 0 ); 151 | if ( len < 0 ) { 152 | printf( "Error: recv() call failed w/errno=%d\n", errno ); 153 | close_socket( listen_sd ); 154 | close_socket( acc_sd ); 155 | exit( 1 ); 156 | } 157 | 158 | 159 | /* 160 | ** All data has been received and transmitted, so close the sockets. 161 | */ 162 | 163 | close_socket( acc_sd ); 164 | close_socket( listen_sd ); 165 | exit( 0 ); 166 | } 167 | 168 | -------------------------------------------------------------------------------- /include/netdb.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** NETDB.H 7 | ** 8 | ** Copyright (c) 1988, The Regents of the University of California. 9 | ** 10 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 11 | ** No part of this program may be copied or used without the prior 12 | ** written consent of Hewlett Packard Company. 13 | */ 14 | 15 | 16 | 17 | struct hostent { 18 | char far *h_name; 19 | char far * far *h_aliases; 20 | int h_addrtype; 21 | int h_length; 22 | struct in_addr far * far *h_addr_list; /* address list returned from */ 23 | /* domain name server */ 24 | #define h_addr h_addr_list[0] /* for backwards compatibility */ 25 | }; 26 | 27 | 28 | struct netent { 29 | char far *n_name; 30 | char far * far *n_aliases; 31 | unsigned long n_net; 32 | int n_addrtype; 33 | }; 34 | 35 | 36 | struct protoent { 37 | char far *p_name; 38 | char far * far *p_aliases; 39 | int p_proto; 40 | }; 41 | 42 | 43 | struct servent { 44 | char far *s_name; 45 | char far * far *s_aliases; 46 | int s_port; 47 | char far *s_proto; 48 | }; 49 | 50 | 51 | /* 52 | ** The following errors are not currently returned by the domain name 53 | ** requester. In Unix systems, these are returned in the extern int 54 | ** variable 'h_errno'. 55 | */ 56 | 57 | /* #define HOST_NOT_FOUND 1 */ /* Authoritative answer not found */ 58 | /* #define TRY_AGAIN 2 */ /* Non-authoritative answer not found */ 59 | /* #define NO_RECOVERY 3 */ /* Non-recoverable error */ 60 | /* #define NO_DATA 4 */ /* Valid name, no data record for type */ 61 | /* #define NO_ADDRESS NO_DATA */ /* No address exists */ 62 | -------------------------------------------------------------------------------- /include/netinet/in.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** IN.H 7 | ** 8 | ** (c) Copyright 1988, The Regents of the University of California. 9 | ** 10 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 11 | */ 12 | 13 | 14 | 15 | /* 16 | ** Protocol numbers defined for use in the IP header protocol field. 17 | ** Currently, these are the only supported protocols. 18 | */ 19 | 20 | #define IPPROTO_TCP 6 /* tcp */ 21 | #define IPPROTO_UDP 17 /* user datagram protocol */ 22 | 23 | 24 | /* 25 | ** Port/socket numbers: network standard functions 26 | */ 27 | 28 | #define IPPORT_ECHO 7 29 | #define IPPORT_DISCARD 9 30 | #define IPPORT_SYSTAT 11 31 | #define IPPORT_DAYTIME 13 32 | #define IPPORT_NETSTAT 15 33 | #define IPPORT_FTP 21 34 | #define IPPORT_TELNET 23 35 | #define IPPORT_SMTP 25 36 | #define IPPORT_TIMESERVER 37 37 | #define IPPORT_NAMESERVER 42 38 | #define IPPORT_WHOIS 43 39 | 40 | 41 | /* 42 | ** Port/socket numbers: host specific functions 43 | */ 44 | 45 | #define IPPORT_TFTP 69 46 | #define IPPORT_RJE 77 47 | #define IPPORT_FINGER 79 48 | #define IPPORT_TTYLINK 87 49 | #define IPPORT_SUPDUP 95 50 | 51 | 52 | /* 53 | ** TCP sockets 54 | */ 55 | 56 | #define IPPORT_EXECSERVER 512 57 | #define IPPORT_LOGINSERVER 513 58 | #define IPPORT_CMDSERVER 514 59 | #define IPPORT_EFSSERVER 520 60 | 61 | 62 | /* 63 | ** UDP sockets 64 | */ 65 | 66 | #define IPPORT_BIFFUDP 512 67 | #define IPPORT_WHOSERVER 513 68 | #define IPPORT_ROUTESERVER 520 69 | 70 | 71 | /* 72 | ** Ports < IPPORT_RESERVED are reserved for 73 | ** privileged processes (e.g. root). 74 | */ 75 | 76 | #define IPPORT_RESERVED 1024 77 | 78 | 79 | /* 80 | ** Definitions of bits in internet address integers. 81 | */ 82 | 83 | #define IN_CLASSA(i) ((((long)(i))&0x80000000)==0) 84 | #define IN_CLASSA_NET 0xff000000 85 | #define IN_CLASSA_NSHIFT 24 86 | #define IN_CLASSA_HOST 0x00ffffff 87 | 88 | #define IN_CLASSB(i) ((((long)(i))&0xc0000000)==0x80000000) 89 | #define IN_CLASSB_NET 0xffff0000 90 | #define IN_CLASSB_NSHIFT 16 91 | #define IN_CLASSB_HOST 0x0000ffff 92 | 93 | #define IN_CLASSC(i) ((((long)(i))&0xc0000000)==0xc0000000) 94 | #define IN_CLASSC_NET 0xffffff00 95 | #define IN_CLASSC_NSHIFT 8 96 | #define IN_CLASSC_HOST 0x000000ff 97 | 98 | #define INADDR_ANY 0x00000000 99 | #define INADDR_BROADCAST 0xffffffff 100 | 101 | /* The following conditional compilation allows in_addr to be defined 102 | ** here and in socket.h. This change was made because the C 6.0 compiler 103 | ** requires sturctures be defined before referenced. */ 104 | 105 | #ifndef IN_ADDR_DEFINE 106 | #define IN_ADDR_DEFINE 107 | struct in_addr { 108 | union { 109 | struct { unsigned char s_b1, s_b2, s_b3, s_b4; } S_un_b; 110 | struct { unsigned short s_w1, s_w2; } S_un_w; 111 | unsigned long S_addr; 112 | } S_un; 113 | }; 114 | #endif 115 | 116 | #define s_addr S_un.S_addr /* for most uses */ 117 | #define s_host S_un.S_un_b.s_b2 /* host on imp */ 118 | #define s_net S_un.S_un_b.s_b1 /* network */ 119 | #define s_imp S_un.S_un_w.s_w2 /* imp */ 120 | #define s_impno S_un.S_un_b.s_b4 /* imp # */ 121 | #define s_lh S_un.S_un_b.s_b3 /* logical host */ 122 | 123 | 124 | struct sockaddr_in { 125 | short sin_family; 126 | unsigned short sin_port; 127 | struct in_addr sin_addr; 128 | char sin_zero[8]; 129 | }; 130 | -------------------------------------------------------------------------------- /include/sock_err.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** SOCK_ERR.H 7 | ** 8 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 9 | ** No part of this program may be copied or used without the prior 10 | ** written consent of Hewlett Packard Company. 11 | */ 12 | 13 | 14 | #define ENOTSOCK 100 /* Socket operation on non-socket */ 15 | #define FIRST_SOCK_ERR ENOTSOCK 16 | 17 | #define EDESTADDRREQ 101 /* Destination address required */ 18 | #define EMSGSIZE 102 /* Message too long */ 19 | #define EPROTOTYPE 103 /* Protocol wrong type for socket */ 20 | #define ENOPROTOOPT 104 /* Protocol not available */ 21 | #define EPROTONOSUPPORT 105 /* Protocol not supported */ 22 | #define ESOCKTNOSUPPORT 106 /* Socket type not supported */ 23 | #define EOPNOTSUPP 107 /* Operation not supported on socket */ 24 | #define EPFNOSUPPORT 108 /* Protocol family not supported */ 25 | #define EAFNOSUPPORT 109 /* Address family not supported by protocol family */ 26 | 27 | #define EADDRINUSE 110 /* Address already in use */ 28 | #define EADDRNOTAVAIL 111 /* Can't assign requested address */ 29 | #define ENETDOWN 112 /* Network is down */ 30 | #define ENETUNREACH 113 /* Network is unreachable */ 31 | #define ENETRESET 114 /* Network dropped connection or reset */ 32 | #define ECONNABORTED 115 /* Software caused connection abort */ 33 | #define ECONNRESET 116 /* Connection reset by peer */ 34 | #define ENOBUFS 117 /* No buffer space available */ 35 | #define EISCONN 118 /* Socket is already connected */ 36 | #define ENOTCONN 119 /* Socket is not connected */ 37 | 38 | #define ESHUTDOWN 120 /* Can't send after socket shutdown */ 39 | #define ETIMEDOUT 121 /* Connection timed out */ 40 | #define ECONNREFUSED 122 /* Connection refused */ 41 | #define EHOSTDOWN 123 /* Networking subsystem not started */ 42 | #define EHOSTUNREACH 124 /* No route to host */ 43 | #define EWOULDBLOCK 125 /* Operation would block */ 44 | #define EINPROGRESS 126 /* Operation now in progress */ 45 | #define EALREADY 127 /* Operation already in progress */ 46 | #define EBADVERSION 128 /* Library/driver version mismatch */ 47 | #define EINVALSOCK 129 /* Invalid argument */ 48 | 49 | #define ETOOMANYSOCK 130 /* Too many open sockets */ 50 | #define EFAULTSOCK 131 /* Bad address in sockets call */ 51 | 52 | #ifdef SOCK_WIN_DLL 53 | #define ENODOSMEM 132 /* windows GlobalDosAlloc call failed */ 54 | #define LAST_SOCK_ERR ENODOSMEM 55 | #elif defined WSOCKETS_DLL 56 | #define ENODOSMEM 132 /* windows GlobalDosAlloc call failed */ 57 | #define EBADRCFILE 133 /* strings file did not load properly */ 58 | #define LAST_SOCK_ERR EBADRCFILE 59 | #else 60 | #define LAST_SOCK_ERR EFAULTSOCK 61 | #endif 62 | 63 | #define MAX_SOCK_ERR_LEN 100 /* maximum length of error text */ 64 | 65 | -------------------------------------------------------------------------------- /include/sockdefs.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** SOCKDEFS.H 7 | ** 8 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 9 | ** No part of this program may be copied or used without the prior 10 | ** written consent of Hewlett Packard Company. 11 | ** 12 | ** Macros are necessary to map standard sockets calls, which set the 13 | ** errno global variable as a side effect of the call, to our 14 | ** implementation-specific library entry points which expect to receive 15 | ** a pointer to the errno variable. This is required since (1) the 16 | ** custom memory model sockets library can't set a global variable 17 | ** in the user's application without receiving a pointer to it (which 18 | ** would require a sockets-interface change), and (2) global variables 19 | ** are not available between dynamic link libraries and user applications. 20 | ** 21 | ** These macros transparently provide full errno functionality without 22 | ** requiring sockets source code changes. 23 | */ 24 | 25 | #define accept(a,b,c) _accept(a,b,c, (int far *) &errno ) 26 | #define bind(a,b,c) _bind(a,b,c, (int far *) &errno ) 27 | #define close_socket(a) _close_socket(a, (int far *) &errno ) 28 | #define connect(a,b,c) _connect(a,b,c, (int far *) &errno ) 29 | #define gethostname(a,b) _gethostname(a,b, (int far *) &errno ) 30 | #define getpeername(a,b,c) _getpeername(a,b,c, (int far *) &errno ) 31 | #define getsockname(a,b,c) _getsockname(a,b,c, (int far *) &errno ) 32 | #define getsockopt(a,b,c,d,e) _getsockopt(a,b,c,d,e, (int far *) &errno ) 33 | #define ioctl(a,b,c) _ioctl(a,b,c, (int far *) &errno ) 34 | #define listen(a,b) _listen(a,b, (int far *) &errno ) 35 | #define recv(a,b,c,d) _recv(a,b,c,d, (int far *) &errno ) 36 | #define recvfrom(a,b,c,d,e,f) _recvfrom(a,b,c,d,e,f, (int far *) &errno ) 37 | #define select(a,b,c,d,e) _select(a,b,c,d,e, (int far *) &errno ) 38 | #define send(a,b,c,d) _send(a,b,c,d, (int far *) &errno ) 39 | #define sendto(a,b,c,d,e,f) _sendto(a,b,c,d,e,f, (int far *) &errno ) 40 | #define setsockopt(a,b,c,d,e) _setsockopt(a,b,c,d,e, (int far *) &errno ) 41 | #define socket(a,b,c) _socket(a,b,c, (int far *) &errno ) 42 | 43 | 44 | /* 45 | ** System calls 46 | */ 47 | 48 | int cdecl far _accept( int, struct sockaddr far *, int far *, int far * ); 49 | int cdecl far _bind( int, struct sockaddr far *, int , int far * ); 50 | int cdecl far _close_socket( int , int far * ); 51 | int cdecl far _connect( int, struct sockaddr far *, int , int far * ); 52 | int cdecl far _gethostname( char far *, int , int far * ); 53 | int cdecl far _getpeername( int, struct sockaddr far *, int far * , int far * ); 54 | int cdecl far _getsockname( int, struct sockaddr far *, int far * , int far * ); 55 | int cdecl far _getsockopt( int, int, int, char far *, int far * , int far * ); 56 | int cdecl far _ioctl( int, int, char far * , int far * ); 57 | int cdecl far _listen( int, int , int far * ); 58 | int cdecl far _recv( int, char far *, int, int , int far * ); 59 | int cdecl far _recvfrom( int, char far *, int, int, struct sockaddr far *, 60 | int far * , int far * ); 61 | int cdecl far _select( int, fd_set far *, fd_set far *, fd_set far *, 62 | struct timeval far * , int far * ); 63 | int cdecl far _send( int, char far *, int, int , int far * ); 64 | int cdecl far _sendto( int, char far *, int, int, struct sockaddr far *, int, 65 | int far * ); 66 | int cdecl far _setsockopt( int, int, int, char far *, int , int far * ); 67 | int cdecl far _socket( int, int, int , int far * ); 68 | 69 | 70 | char far * cdecl far sock_strerror( int ); 71 | 72 | 73 | 74 | /* 75 | ** inet_*, byte swapping routines 76 | */ 77 | 78 | unsigned long cdecl far inet_addr( char far * ); 79 | long cdecl far inet_lnaof( struct in_addr ); 80 | struct in_addr cdecl far inet_makeaddr( unsigned long, unsigned long ); 81 | long cdecl far inet_netof( struct in_addr ); 82 | unsigned long cdecl far inet_network( char far * ); 83 | char far *cdecl far inet_ntoa( struct in_addr ); 84 | 85 | int cdecl far htons( int ), cdecl far ntohs( int ); 86 | unsigned long cdecl far htonl( long ), cdecl far ntohl( long ); 87 | 88 | 89 | /* 90 | ** library calls 91 | */ 92 | 93 | void cdecl far sethostent( int ); 94 | void cdecl far endhostent( void ); 95 | struct hostent far *cdecl far gethostent( void ); 96 | struct hostent far *cdecl far gethostbyname( char far * ); 97 | struct hostent far *cdecl far gethostbyaddr( struct in_addr far *, int, int ); 98 | 99 | void cdecl far setnetent( int ); 100 | void cdecl far endnetent( void ); 101 | struct netent far *cdecl far getnetent( void ); 102 | struct netent far *cdecl far getnetbyname( char far * ); 103 | struct netent far *cdecl far getnetbyaddr( unsigned long, int ); 104 | 105 | void cdecl far setprotoent( int ); 106 | void cdecl far endprotoent( void ); 107 | struct protoent far *cdecl far getprotoent( void ); 108 | struct protoent far *cdecl far getprotobyname( char far * ); 109 | struct protoent far *cdecl far getprotobynumber( int ); 110 | 111 | void cdecl far setservent( int ); 112 | void cdecl far endservent( void ); 113 | struct servent far *cdecl far getservent( void ); 114 | struct servent far *cdecl far getservbyname( char far *, char far * ); 115 | struct servent far *cdecl far getservbyport( int, char far * ); 116 | 117 | -------------------------------------------------------------------------------- /include/sys/socket.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** SOCKET.H 7 | ** 8 | ** (c) Copyright 1988, The Regents of the University of California. 9 | ** 10 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 11 | ** No part of this program may be copied or used without the prior 12 | ** written consent of Hewlett Packard Company. 13 | */ 14 | 15 | 16 | /* 17 | ** Parameters 18 | */ 19 | 20 | #define MAXHOSTNAMELEN 17 /* 16 character name + null terminator */ 21 | 22 | #define MAX_SOCKETS 64 /* Maximum number of sockets supported. */ 23 | /* This should NOT be changed by the */ 24 | /* user to enable more sockets. The */ 25 | /* sockets libraries have been compiled */ 26 | /* with this value and altering it */ 27 | /* would cause sockets failures. */ 28 | 29 | #define SOL_SOCKET 0xffff /* level for get/setsockopt() calls */ 30 | 31 | 32 | 33 | /* 34 | ** linger structure for get/setsockopt(), timeval structure for select() 35 | */ 36 | 37 | struct linger { 38 | int l_onoff; 39 | int l_linger; 40 | }; 41 | 42 | struct timeval { 43 | unsigned long tv_sec; 44 | unsigned long tv_usec; 45 | }; 46 | 47 | 48 | /* 49 | ** defines, types required for select() 50 | */ 51 | 52 | #define RM_OFFSET(n) (n & 0x00ff) 53 | #define ADD_OFFSET(n) (n | 0x0100) 54 | #define MASK_BYTES ((MAX_SOCKETS / 8) + (MAX_SOCKETS % 8 == 0 ? 0 : 1)) 55 | 56 | #define FD_SET(n,p) ((p)->mask[(RM_OFFSET(n))/8] |= (1 << (RM_OFFSET(n)) % 8)) 57 | #define FD_CLR(n,p) ((p)->mask[(RM_OFFSET(n))/8] &= ~(1 << (RM_OFFSET(n)) % 8)) 58 | #define FD_ISSET(n,p) ((p)->mask[(RM_OFFSET(n))/8] & (1 << (RM_OFFSET(n)) % 8)) 59 | #define FD_ZERO(p) \ 60 | { \ 61 | int _loopct; \ 62 | for(_loopct=0;_loopctmask[_loopct]=0; \ 64 | } \ 65 | } 66 | 67 | typedef struct { char mask[MASK_BYTES]; } fd_set; 68 | 69 | 70 | /* 71 | ** Socket types supported 72 | */ 73 | 74 | #define SOCK_STREAM 1 /* stream sockets interface */ 75 | #define SOCK_DGRAM 2 /* datagram sockets interface */ 76 | 77 | /* 78 | ** socket options 79 | */ 80 | 81 | #define SO_DEBUG 0x01 /* turn on debugging info */ 82 | /* don't allocate 0x02 for an option */ 83 | #define SO_REUSEADDR 0x04 /* allow local address reuse */ 84 | #define SO_KEEPALIVE 0x08 /* keep connections alive */ 85 | #define SO_DONTROUTE 0x10 86 | #define SO_TYPE 0x20 /* used for getsockopt() */ 87 | #define SO_LINGER 0x80 /* linger on close if data present */ 88 | 89 | #define SO_PROCESS_ID 0x0100 /* used to transfer socket ownership */ 90 | 91 | #define SO_DONTLINGER (~SO_LINGER) 92 | 93 | 94 | /* 95 | ** Only flags supported for send(), recv() families 96 | */ 97 | 98 | #define MSG_PEEK 0x02 99 | #define MSG_PUSH 0x04 100 | 101 | 102 | /* 103 | ** Only ioctl flags supported 104 | */ 105 | 106 | #define FIONBIO 0x0001 107 | #define FIONREAD 0x0002 108 | 109 | 110 | /* 111 | ** address families supported 112 | */ 113 | 114 | #define AF_UNSPEC 0 115 | #define AF_INET 2 116 | 117 | 118 | /* 119 | ** Maximum queue length (aka backlog) that may be specified by listen() 120 | */ 121 | 122 | #define SOMAXCONN 5 123 | 124 | struct sockaddr { 125 | unsigned short sa_family; /* address family */ 126 | char sa_data[14]; /* up to 14 bytes for general address use*/ 127 | }; 128 | 129 | struct sockproto { 130 | unsigned short sp_family; /* address family */ 131 | unsigned short sp_protocol; /* protocol */ 132 | }; 133 | 134 | /* The following is included because C6.0 requires that structures be 135 | ** defined before referenced. addr_in is referenced in the function 136 | ** prototypes include below. It is defined in netinet\in.h. The 137 | ** conditional compilation in this file and in netinet\in.h allows 138 | ** these files to be included in any order. */ 139 | 140 | #ifndef IN_ADDR_DEFINE 141 | #define IN_ADDR_DEFINE 142 | struct in_addr { 143 | union { 144 | struct { unsigned char s_b1, s_b2, s_b3, s_b4; } S_un_b; 145 | struct { unsigned short s_w1, s_w2; } S_un_w; 146 | unsigned long S_addr; 147 | } S_un; 148 | }; 149 | #endif 150 | 151 | #ifdef SOCK_WIN_DLL 152 | #define HOST_INFO_SIZE 420 153 | #define NET_INFO_SIZE 200 154 | #define PROTO_INFO_SIZE 200 155 | #define SERV_INFO_SIZE 200 156 | #define IPADDR_STR_LEN 20 157 | /* pkb used 100 because thats what it is in lib_incl.h */ 158 | #define ASCII_DB_PATH_LEN 100 159 | 160 | #include 161 | 162 | #elif defined WSOCKETS_DLL 163 | #include 164 | 165 | #else 166 | #include 167 | #endif 168 | -------------------------------------------------------------------------------- /include/wsockdef.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | ** WSOCKDEF.H 7 | ** 8 | ** Copyright (c) Hewlett Packard Company, 1989. All rights reserved. 9 | ** No part of this program may be copied or used without the prior 10 | ** written consent of Hewlett Packard Company. 11 | ** 12 | */ 13 | 14 | /* 15 | ** System calls 16 | */ 17 | 18 | short far pascal WinAccept( unsigned int, short, struct sockaddr far *, 19 | short far *, short far * ); 20 | short far pascal WinBind( unsigned int, short, struct sockaddr far *, 21 | short, short far * ); 22 | short far pascal WinCloseSocket( unsigned int, short, short far * ); 23 | short far pascal WinConnect( unsigned int, short, struct sockaddr far *, 24 | short , short far * ); 25 | short far pascal WinGetHostname( char far *, short , short far * ); 26 | short far pascal WinGetPeerName( unsigned int, short, struct sockaddr far *, 27 | short far * , short far * ); 28 | short far pascal WinGetSockName( unsigned int, short, struct sockaddr far *, 29 | short far * , short far * ); 30 | short far pascal WinGetSockOpt( unsigned int, short, short, short, char far *, 31 | short far * , short far * ); 32 | short far pascal WinIoctl( unsigned int, short, short, char far * , short far * ); 33 | short far pascal WinListen( unsigned int, short, short , short far * ); 34 | short far pascal WinRecv( unsigned int, short, char far *, short, short, 35 | short far * ); 36 | short far pascal WinRecvFrom( unsigned int, short, char far *, short, short, 37 | struct sockaddr far *, short far * , short far * ); 38 | short far pascal WinSelect( unsigned int, short, fd_set far *, fd_set far *, 39 | fd_set far *, struct timeval far * , short far * ); 40 | short far pascal WinSend( unsigned int, short, char far *, short, short, 41 | short far * ); 42 | short far pascal WinSendTo( unsigned int, short, char far *, short, short, 43 | struct sockaddr far *, short, short far * ); 44 | short far pascal WinSetSockOpt( unsigned int, short, short, short, 45 | char far *, short, short far * ); 46 | short far pascal WinSocket( unsigned int, short, short, short , short far * ); 47 | 48 | 49 | /* 50 | ** short far pascal win_sock_strerror( short, char far * ); 51 | */ 52 | 53 | short far pascal WinSockStrError( short, char far *); 54 | 55 | 56 | /* 57 | ** inet_*, byte swapping routines 58 | */ 59 | 60 | unsigned long far pascal WinInetAddr( char far * ); 61 | long far pascal WinInetLNAOF( struct in_addr ); 62 | struct in_addr far pascal WinInetMakeAddr( unsigned long, unsigned long ); 63 | long far pascal WinInetNetOF( struct in_addr ); 64 | unsigned long far pascal WinInetNetwork( char far * ); 65 | short far pascal WinInetNToA( struct in_addr, char far * ); 66 | 67 | unsigned short far pascal WinHToNS( unsigned short ); 68 | unsigned short far pascal WinNToHS( unsigned short ); 69 | unsigned long far pascal WinHToNL( unsigned long ); 70 | unsigned long far pascal WinNToHL( unsigned long ); 71 | 72 | 73 | /* 74 | ** library calls 75 | */ 76 | 77 | short far pascal WinGetAsciiDBPath( char far * ); 78 | 79 | short far pascal WinGetHostByName( char far *, char far * ); 80 | short far pascal WinGetHostByAddr( struct in_addr far *, short, 81 | short, char far * ); 82 | 83 | short far pascal WinGetNetByName( char far *, char far * ); 84 | short far pascal WinGetNetByAddr( unsigned long, short, char far * ); 85 | 86 | short far pascal WinGetProtoByName( char far *, char far * ); 87 | short far pascal WinGetProtoByNumber( short, char far * ); 88 | 89 | short far pascal WinGetServByName( char far *, char far *, char far * ); 90 | short far pascal WinGetServByPort( short, char far *, char far * ); 91 | 92 | 93 | /* 94 | ** Library initialization, free calls (for static lib interface) 95 | */ 96 | 97 | unsigned int far pascal WinInitSockLib( void ); 98 | void far pascal WinFreeSockLib( unsigned int ); 99 | 100 | -------------------------------------------------------------------------------- /include/wsockets.h: -------------------------------------------------------------------------------- 1 | /* COPYRIGHT, (c) HEWLETT PACKARD CO. 1990,1991 */ 2 | /* All rights reserved. No part of this program */ 3 | /* may be copied or used without the express */ 4 | /* written consent of HEWLETT PACKARD Corp. */ 5 | /* 6 | /* WSOCKDEF.H 7 | */ 8 | 9 | /* Traditional sockets implementations relie on using static 10 | ** memory in the sockets library. Since this sockets implementation 11 | ** is a DLL not a static library, memory areas are provided in 12 | ** this header file and transparently added to the sockets calls 13 | ** via macros. Note that even if you include this header file multiple 14 | ** times only 1 set of variables will be declared. 15 | */ 16 | 17 | #ifndef SOCK_MEMORY_AREAS 18 | #define SOCK_MEMORY_AREAS 19 | #define HOST_INFO_SIZE 420 20 | #define NET_INFO_SIZE 200 21 | #define PROTO_INFO_SIZE 200 22 | #define SERV_INFO_SIZE 200 23 | #define IPADDR_STR_LEN 20 24 | #define ASCII_DB_PATH_LEN 100 25 | 26 | /* variable definitions for static memory areas */ 27 | int errno; 28 | char host_buff[HOST_INFO_SIZE]; 29 | char net_buff[NET_INFO_SIZE]; 30 | char proto_buff[PROTO_INFO_SIZE]; 31 | char serv_buff[SERV_INFO_SIZE]; 32 | char ntoa_buff[IPADDR_STR_LEN]; 33 | #endif 34 | 35 | /* 36 | ** 37 | ** Macros are necessary to map standard sockets calls, which set the 38 | ** errno global variable as a side effect of the call, to our 39 | ** implementation-specific library entry points which expect to receive 40 | ** a pointer to the errno variable. This is required since (1) the 41 | ** custom memory model sockets library can't set a global variable 42 | ** in the user's application without receiving a pointer to it (which 43 | ** would require a sockets-interface change), and (2) global variables 44 | ** are not available between dynamic link libraries and user applications. 45 | ** 46 | ** These macros transparently provide full errno functionality without 47 | ** requiring sockets source code changes. 48 | */ 49 | 50 | #define accept(a,b,c) w_accept(a,b,c, (int far *) &errno ) 51 | #define bind(a,b,c) w_bind(a,b,c, (int far *) &errno ) 52 | #define close_socket(a) w_close_socket(a, (int far *) &errno ) 53 | #define connect(a,b,c) w_connect(a,b,c, (int far *) &errno ) 54 | #define gethostname(a,b) w_gethostname(a,b, (int far *) &errno ) 55 | #define getpeername(a,b,c) w_getpeername(a,b,c, (int far *) &errno ) 56 | #define getsockname(a,b,c) w_getsockname(a,b,c, (int far *) &errno ) 57 | #define getsockopt(a,b,c,d,e) w_getsockopt(a,b,c,d,e, (int far *) &errno ) 58 | #define ioctl(a,b,c) w_ioctl(a,b,c, (int far *) &errno ) 59 | #define listen(a,b) w_listen(a,b, (int far *) &errno ) 60 | #define recv(a,b,c,d) w_recv(a,b,c,d, (int far *) &errno ) 61 | #define recvfrom(a,b,c,d,e,f) w_recvfrom(a,b,c,d,e,f, (int far *) &errno ) 62 | #define select(a,b,c,d,e) w_select(a,b,c,d,e, (int far *) &errno ) 63 | #define send(a,b,c,d) w_send(a,b,c,d, (int far *) &errno ) 64 | #define sendto(a,b,c,d,e,f) w_sendto(a,b,c,d,e,f, (int far *) &errno ) 65 | #define setsockopt(a,b,c,d,e) w_setsockopt(a,b,c,d,e, (int far *) &errno ) 66 | #define socket(a,b,c) w_socket(a,b,c, (int far *) &errno ) 67 | 68 | 69 | /* 70 | ** Macros are also necessary to map standard sockets file access calls. 71 | ** In unix this calls depend on using static memory in the library. 72 | ** Since this sockets implementation is a DLL not a static library 73 | ** macros are provided to pass buffer to be used for the file access 74 | ** information to the DLL. 75 | */ 76 | 77 | #define gethostbyname(a) w_gethostbyname(a,host_buff) 78 | #define gethostbyaddr(a,b,c) w_gethostbyaddr(a,b,c,host_buff) 79 | 80 | #define getnetbyname(a) w_getnetbyname(a,net_buff) 81 | #define getnetbyaddr(a,b) w_getnetbyaddr(a,b,net_buff) 82 | 83 | #define getprotobyname(a) w_getprotobyname(a,proto_buff) 84 | #define getprotobynumber(a) w_getprotobynumber(a,proto_buff) 85 | 86 | #define getservbyname(a,b) w_getservbyname(a,b,serv_buff) 87 | #define getservbyport(a,b) w_getservbyport(a,b,serv_buff) 88 | 89 | #define inet_ntoa(a) w_inet_ntoa(a, ntoa_buff) 90 | 91 | /* 92 | ** System calls 93 | */ 94 | 95 | int pascal far w_accept( int, struct sockaddr far *, int far *, int far * ); 96 | int pascal far w_bind( int, struct sockaddr far *, int , int far * ); 97 | int pascal far w_close_socket( int , int far * ); 98 | int pascal far w_connect( int, struct sockaddr far *, int , int far * ); 99 | int pascal far w_gethostname( char far *, int , int far * ); 100 | int pascal far w_getpeername( int, struct sockaddr far *, int far * , int far * ); 101 | int pascal far w_getsockname( int, struct sockaddr far *, int far * , int far * ); 102 | int pascal far w_getsockopt( int, int, int, char far *, int far * , int far * ); 103 | int pascal far w_ioctl( int, int, char far * , int far * ); 104 | int pascal far w_listen( int, int , int far * ); 105 | int pascal far w_recv( int, char far *, int, int , int far * ); 106 | int pascal far w_recvfrom( int, char far *, int, int, struct sockaddr far *, 107 | int far * , int far * ); 108 | int pascal far w_select( int, fd_set far *, fd_set far *, fd_set far *, 109 | struct timeval far * , int far * ); 110 | int pascal far w_send( int, char far *, int, int , int far * ); 111 | int pascal far w_sendto( int, char far *, int, int, struct sockaddr far *, int, 112 | int far * ); 113 | int pascal far w_setsockopt( int, int, int, char far *, int , int far * ); 114 | int pascal far w_socket( int, int, int , int far * ); 115 | 116 | 117 | int pascal far sock_strerror( int, char far * ); 118 | 119 | /* 120 | ** inet_*, byte swapping routines 121 | */ 122 | 123 | unsigned long pascal far inet_addr( char far * ); 124 | unsigned long pascal far inet_lnaof( struct in_addr ); 125 | struct in_addr pascal far inet_makeaddr( unsigned long, unsigned long ); 126 | unsigned long pascal far inet_netof( struct in_addr ); 127 | unsigned long pascal far inet_network( char far * ); 128 | char far *pascal far w_inet_ntoa( struct in_addr, char far * ); 129 | 130 | unsigned short pascal far htons( unsigned short ); 131 | unsigned short pascal far ntohs( unsigned short ); 132 | unsigned long pascal far htonl( unsigned long ); 133 | unsigned long pascal far ntohl( unsigned long ); 134 | 135 | /* 136 | ** library calls 137 | */ 138 | 139 | struct hostent far * pascal far w_gethostbyname( char far *, char far * ); 140 | struct hostent far * pascal far w_gethostbyaddr( struct in_addr far *, int, 141 | int, char far * ); 142 | 143 | struct netent far * pascal far w_getnetbyname( char far * , char far *); 144 | struct netent far * pascal far w_getnetbyaddr( unsigned long, int, char far * ); 145 | 146 | struct protoent far * pascal far w_getprotobyname( char far *, char far * ); 147 | struct protoent far * pascal far w_getprotobynumber( int, char far * ); 148 | 149 | struct servent far * pascal far w_getservbyname( char far *, char far *, char far * ); 150 | struct servent far * pascal far w_getservbyport( int, char far *, char far * ); 151 | 152 | int far pascal getasciidbpath(char far *); 153 | -------------------------------------------------------------------------------- /lib/dos_sock.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/lib/dos_sock.lib -------------------------------------------------------------------------------- /lib/os2_sock.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/lib/os2_sock.lib -------------------------------------------------------------------------------- /lib/wsockets.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/lib/wsockets.dll -------------------------------------------------------------------------------- /lib/wsockets.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/lib/wsockets.lib -------------------------------------------------------------------------------- /netprog/sockets.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/netprog/sockets.exe -------------------------------------------------------------------------------- /orig/mstcpsdk.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jduerstock/mstcpsdk/c9b40158bd9cce86ecdcd1b9bea61663575202c9/orig/mstcpsdk.rar -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | Microsoft TCP/IP Sockets Development Kit 2 | 3 | Version 1.0 4 | 5 | SUPPLEMENTAL INFORMATION 6 | 7 | 8 | Copyright (c) Hewlett-Packard Company, 1990. 9 | Copyright (c) Microsoft, 1992. All rights reserved. 10 | 11 | Microsoft, MS, and MS-DOS are registered trademarks and Windows is a 12 | trademark of Microsoft Corporation. 13 | 14 | Operating System/2 and OS/2 are registered trademarks licensed to 15 | Microsoft Corporation. U.S. Patent Number 4955066. 16 | 17 | 18 | 19 | This file reflects last-minute information regarding the Microsoft 20 | TCP/IP Sockets Development Kit version 1.0. 21 | 22 | Installing the Microsoft TCP/IP Sockets Development Kit 23 | ------------------------------------------------------- 24 | 25 | The following files are included in the Microsoft TCP/IP Sockets 26 | Development Kit: 27 | 28 | README.TXT - this file 29 | 30 | \INCLUDE\ - the same include files are used for MS-DOS/Windows and 31 | OS/2 application development. By default, the libraries 32 | are used for MS-DOS or OS/2 application development. To 33 | designate Windows development, you must define the symbol 34 | WSOCKETS_DLL before including these files. See Windows 35 | sample apps. 36 | 37 | NETDB.H - defines data structures used by the sockets network 38 | database routines (gethostent, getservent, etc.). 39 | 40 | NETINET\ 41 | IN.H - definitions particular to the Internet address domain. 42 | 43 | SOCK_ERR.H - defines errors returned by sockets routines. 44 | 45 | SOCKDEFS.H - function prototypes for MS-DOS and OS/2 sockets 46 | routines. (Note: included in socket.h). 47 | 48 | WSOCKDEF.H - function prototypes for Windows sockets routines. 49 | (Note: included in socket.h if WSOCKETS_DLL is 50 | defined.) 51 | SYS\ 52 | SOCKET.H - contains socket definitions and type declarations 53 | necessary for most sockets applications. 54 | 55 | \LIB\ 56 | DOS_SOCK.LIB - This library is for MS-DOS sockets applications. 57 | 58 | OS2_SOCK.LIB - This library is for OS/2 sockets applications. 59 | 60 | WSOCKETS.LIB - This is a small static library that is used to 61 | handle the explicit loading of wsockets.dll. 62 | wsockets.dll is included with the LAN Manager 63 | product. See the following sections on Sockets 64 | DLL/Library and Static vs. Dynamic Link Library 65 | Interfaces. 66 | 67 | \DSAMPLE\ - this directory contains sample code for an MS-DOS or 68 | OS/2 (not Windows) application. 69 | 70 | CLIENT.C - sample client application source code. 71 | 72 | SERVER.C - sample server application source code. 73 | 74 | WSAMPLE\ - this directory contains Windows sample code 75 | 76 | CLNT_SRV\ - sample client/server application source code for 77 | Windows. 78 | 79 | UDP\ - source for a very simple UDP Windows application. 80 | 81 | \NETPROG\ 82 | 83 | SOCKETS.EXE - a patched version of socktsr.exe/sockets.exe that 84 | contains a bug fix not found in earlier versions of LAN Manager 2.1 85 | and Microsoft TCP/IP Utilities for LAN Manager. 86 | 87 | You may freely copy the contents of this diskette to your hard disk, 88 | taking care to preserve the include file directory structure. After 89 | indicating to your compiler and linker the location of the include 90 | files and sockets libraries, you should be able to completely build 91 | your application. 92 | 93 | 94 | Sockets DLL/library 95 | ------------------- 96 | The sockets DLL named 'wsockets.dll will be made available to end 97 | users on the LAN Manager distribution diskettes. The user will be 98 | required to copy this file manually from the distribution disk - it 99 | is *not* copied during the installation of LAN Manager by default. It 100 | is also important to remind users that they must load either 101 | socktsr.exe (the old real-mode sockets TSR) or sockets.exe. 102 | 103 | 104 | Wsockets.DLL/sockets.exe bug fixes 105 | ---------------------------------- 106 | A bug fix was made to both wsockets.dll that caused some applications 107 | to UAE when the remote system closed the socket first in a TCP 108 | connection. This bug fix will be incorporated into all new releases 109 | of Microsoft LAN Manager and The Microsoft TCP/IP Utilities for LAN 110 | Manager. For your reference, these updates are provided on this 111 | diskette. 112 | 113 | 114 | Memory Implications 115 | ------------------- 116 | This implementation of sockets attempts to minimize the memory required 117 | to execute sockets applications. There are numerous situations in which 118 | not enough resources are available to fully execute a sockets call, and 119 | sockets indicates this to the user by returning the ENOBUFS error. If 120 | your application receives this error frequently, you should evaluate the 121 | cause, and adjust your PROTOCOL.INI parameters to provide increased 122 | resources. 123 | 124 | 125 | Maximum SOCK_DGRAM send size 126 | ---------------------------- 127 | Currently, the maximum SOCK_DGRAM (UDP) send size is limited to 1400 128 | bytes by the networking services below sockets. IP fragmentation on 129 | UDP transmission is likewise not yet supported. 130 | -------------------------------------------------------------------------------- /wsample/clnt_srv/client.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | 3 | PROGRAM: client.c 4 | 5 | PURPOSE: client sample application 6 | This is a very simple application to demonstrate a stream connection 7 | over the windows sockets dll. It establishes a connection to 8 | win_server_node (This name must be in your hosts file.), 9 | at port number 1041 and then sends and receives 10 packets. After 10 | the 10 packets are sent, a close packet is sent and the socket is 11 | closed. 12 | 13 | FUNCTIONS: 14 | Called by windows---- 15 | WinMain() - calls initialization function, processes message loop 16 | InitApplication() - initializes window data and registers window 17 | InitInstance() - saves instance handle and creates main window 18 | MainWndProc() - processes messages 19 | AboutProc() - processes messages for "About" dialog box 20 | 21 | Called internally---- 22 | cl_setup() - Sets the timer, loads the windows sockets dll, 23 | establishes the connection and does the 1st send. 24 | data_xfer() - does a receive followed by a send each time it is called. 25 | When 10 send and receive are complete, calls cleanup. 26 | cleanup() - Kills the timer, sends the close packet, closes the socket 27 | and frees the windows socket dll. 28 | inc_nI() - increments the line number in the screen output buffer. 29 | 30 | ****************************************************************************/ 31 | 32 | #include "windows.h" /* required for all Windows applications */ 33 | #include "client.h" /* specific to this program */ 34 | 35 | /* WSOCKETS_DLL must be defined before including socket.h */ 36 | #define WSOCKETS_DLL 37 | #include 38 | #include 39 | #include 40 | 41 | /* Global Variables used in windows calls */ 42 | HANDLE hInst; /* current instance */ 43 | short xChar, yChar ; 44 | 45 | /* variables for the screen output buffer */ 46 | char szTextarr[MAXLINES][80]; 47 | short nTextlarr[MAXLINES]; 48 | int nI; 49 | 50 | /* The application state variable. Possible values are NOT_STARTED and 51 | * XFER_ACTIVE. 52 | */ 53 | int nTest_state = NOT_STARTED; 54 | 55 | /* variables for socket activity */ 56 | int nSd; 57 | unsigned nTotal_packets; 58 | char sRecvbuff[BUFFER_SIZE]; 59 | char sSendbuff[BUFFER_SIZE]; 60 | 61 | /**************************************************************************** 62 | 63 | FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) 64 | 65 | PURPOSE: calls initialization function, processes message loop 66 | 67 | COMMENTS: 68 | 69 | Windows recognIzes this function by name as the initial entry point 70 | for the program. This function calls the application initialization 71 | routine, if no other instance of the program is running, and always 72 | calls the instance initialization routine. It then executes a message 73 | retrieval and dispatch loop that is the top-level control structure 74 | for the remainder of execution. The loop is terminated when a WM_QUIT 75 | message is received, at which time this function exits the application 76 | instance by returning the value passed by PostQuitMessage(). 77 | 78 | If this function must abort before entering the message loop, it 79 | returns the conventional value NULL. 80 | 81 | ****************************************************************************/ 82 | 83 | int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) 84 | HANDLE hInstance; /* current instance */ 85 | HANDLE hPrevInstance; /* previous instance */ 86 | LPSTR lpCmdLine; /* command line */ 87 | int nCmdShow; /* show-window type (open/icon) */ 88 | { 89 | MSG msg; /* message */ 90 | 91 | if (!hPrevInstance) /* Other instances of app running? */ 92 | if (!InitApplication(hInstance)) /* Initialize shared things */ 93 | return (FALSE); /* Exits if unable to initialize */ 94 | 95 | /* Perform initializations that apply to a specific instance */ 96 | 97 | if (!InitInstance(hInstance, nCmdShow)) 98 | return (FALSE); 99 | 100 | /* Acquire and dispatch messages until a WM_QUIT message is received. */ 101 | 102 | while (GetMessage(&msg, /* message structure */ 103 | NULL, /* handle of window receiving the message */ 104 | NULL, /* lowest message to examine */ 105 | NULL)) /* highest message to examine */ 106 | { 107 | TranslateMessage(&msg); /* Translates virtual key codes */ 108 | DispatchMessage(&msg); /* Dispatches message to window */ 109 | } 110 | 111 | return (msg.wParam); /* Returns the value from PostQuitMessage */ 112 | } 113 | 114 | 115 | /**************************************************************************** 116 | 117 | FUNCTION: InitApplication(HANDLE) 118 | 119 | PURPOSE: Initializes window data and registers window class 120 | 121 | COMMENTS: 122 | 123 | This function is called at initialization time only if no other 124 | instances of the application are running. This function performs 125 | initialization tasks that can be done once for any number of running 126 | instances. 127 | 128 | In this case, we initialize a window class by filling out a data 129 | structure of type WNDCLASS and calling the Windows RegisterClass() 130 | function. Since all instances of this application use the same window 131 | class, we only need to do this when the first instance is initialized. 132 | 133 | 134 | ****************************************************************************/ 135 | 136 | BOOL InitApplication(hInstance) 137 | HANDLE hInstance; /* current instance */ 138 | { 139 | HANDLE hMemory; 140 | PWNDCLASS pWndClass; 141 | BOOL bSuccess; 142 | 143 | hMemory = LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT),sizeof(WNDCLASS)); 144 | pWndClass = (PWNDCLASS) LocalLock(hMemory); 145 | 146 | /* Fill in window class structure with parameters that describe the */ 147 | /* main window. */ 148 | 149 | pWndClass->style = NULL; /* Class style(s). */ 150 | pWndClass->lpfnWndProc = MainWndProc; /* Function to retrieve messages */ 151 | /* windows of this class. */ 152 | pWndClass->cbClsExtra = 0; /* No per-class extra data. */ 153 | pWndClass->cbWndExtra = 0; /* No per-window extra data */ 154 | pWndClass->hInstance = hInstance; /* Application that owns the class. */ 155 | pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION); 156 | pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW); 157 | pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH); 158 | pWndClass->lpszMenuName = "ClientMenu"; /* Name of menu resource in .RC file. */ 159 | pWndClass->lpszClassName = "ClientWClass"; /* Name used in call to CreateWindow. */ 160 | 161 | /* Register the window class and return success/failure code. */ 162 | 163 | bSuccess= (RegisterClass(pWndClass)); 164 | 165 | LocalUnlock(hMemory); 166 | LocalFree(hMemory); 167 | return (bSuccess); 168 | 169 | } 170 | 171 | 172 | /**************************************************************************** 173 | 174 | FUNCTION: InitInstance(HANDLE, int) 175 | 176 | PURPOSE: Saves instance handle and creates main window 177 | 178 | COMMENTS: 179 | 180 | This function is called at initialization time for every instance of 181 | this application. This function performs initialization tasks that 182 | cannot be shared by multiple instances. 183 | 184 | In this case, we save the instance handle in a static variable and 185 | create and display the main program window. 186 | 187 | ****************************************************************************/ 188 | 189 | BOOL InitInstance(hInstance, nCmdShow) 190 | HANDLE hInstance; /* Current instance identifier. */ 191 | int nCmdShow; /* Param for first ShowWindow() call. */ 192 | { 193 | HWND hWnd; /* Main window handle. */ 194 | 195 | /* Save the instance handle in static variable, which will be used in */ 196 | /* many subsequence calls from this application to Windows. */ 197 | 198 | hInst = hInstance; 199 | 200 | /* Create a main window for this application instance. */ 201 | 202 | hWnd = CreateWindow( 203 | "ClientWClass", /* See RegisterClass() call. */ 204 | "Sample Client Application", /* Text for window title bar. */ 205 | WS_OVERLAPPEDWINDOW, /* Window style. */ 206 | CW_USEDEFAULT, /* Default horizontal position. */ 207 | CW_USEDEFAULT, /* Default vertical position. */ 208 | CW_USEDEFAULT, /* Default width. */ 209 | CW_USEDEFAULT, /* Default height. */ 210 | NULL, /* Overlapped windows have no parent. */ 211 | NULL, /* Use the window class menu. */ 212 | hInstance, /* This instance owns this window. */ 213 | NULL /* Pointer not needed. */ 214 | ); 215 | 216 | /* If window could not be created, return "failure" */ 217 | 218 | if (!hWnd) 219 | return (FALSE); 220 | 221 | /* Make the window visible; update its client area; and return "success" */ 222 | 223 | ShowWindow(hWnd, nCmdShow); /* Show the window */ 224 | UpdateWindow(hWnd); /* Sends WM_PAINT message */ 225 | return (TRUE); /* Returns the value from PostQuitMessage */ 226 | 227 | } 228 | 229 | /**************************************************************************** 230 | 231 | FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG) 232 | 233 | PURPOSE: Processes messages 234 | 235 | MESSAGES: 236 | 237 | WM_CREATE - create window 238 | WM_PAINT - repaint window 239 | WM_COMMAND messages 240 | IDM_CLSTART - start the connection 241 | IDM_ABOUT - display About dialog box 242 | WM_TIMER - Set timer interval has expired 243 | WM_DESTROY - destroy window 244 | 245 | COMMENTS: 246 | 247 | ****************************************************************************/ 248 | 249 | long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam) 250 | HWND hWnd; /* window handle */ 251 | unsigned message; /* type of message */ 252 | WORD wParam; /* additional information */ 253 | LONG lParam; /* additional information */ 254 | { 255 | FARPROC lpProc; /* pointer to a function */ 256 | HDC hDC; 257 | TEXTMETRIC tm; 258 | PAINTSTRUCT ps; 259 | 260 | int nJ; 261 | 262 | switch (message) { 263 | 264 | case WM_CREATE: 265 | hDC = GetDC(hWnd); 266 | GetTextMetrics(hDC, &tm); 267 | xChar = tm.tmAveCharWidth; 268 | yChar = tm.tmHeight + tm.tmExternalLeading; 269 | ReleaseDC(hWnd, hDC); 270 | break; 271 | 272 | case WM_PAINT: 273 | /* This program has a simplistic output method. It repaints 274 | * the entire screen for every WM_PAINT message. Each time 275 | * it adds a line of output it calls inc_nI() to increment the 276 | * line number in the output buffer, and it calls InvalidateRect() 277 | * so the screen will be repainted. 278 | */ 279 | if (nI==0) { 280 | return (DefWindowProc(hWnd, message, wParam, lParam)); 281 | } 282 | BeginPaint(hWnd,&ps); 283 | for (nJ=1;nJ<=nI;nJ++) { 284 | TextOut(ps.hdc,xChar,yChar *nJ,&szTextarr[nJ-1][0],nTextlarr[nJ-1]); 285 | } 286 | EndPaint (hWnd, &ps); 287 | break; 288 | 289 | case WM_COMMAND: /* message: command from application menu */ 290 | switch (wParam){ 291 | case IDM_CLSTART: 292 | if (nTest_state == XFER_ACTIVE) { 293 | MessageBox(hWnd, 294 | "Already executing sample client application. PLEASE wait.", 295 | "Error", 296 | MB_OK); 297 | } else { 298 | cl_setup(hWnd); 299 | } 300 | break; 301 | 302 | case IDM_ABOUT: 303 | lpProc = MakeProcInstance(AboutProc, hInst); 304 | DialogBox(hInst, "AboutBox", hWnd, lpProc); 305 | FreeProcInstance(lpProc); 306 | break; 307 | 308 | } 309 | break; 310 | 311 | 312 | case WM_TIMER: /* message: Timer message */ 313 | if (nTest_state==XFER_ACTIVE) { 314 | data_xfer(hWnd); 315 | } 316 | else { 317 | MessageBox(hWnd, 318 | "state error, timer expired and not in XFER_ACTIVE state.", 319 | "Error", 320 | MB_OK); 321 | } 322 | break; 323 | case WM_DESTROY: /* message: window being destroyed */ 324 | if (nTest_state==XFER_ACTIVE) 325 | cleanup(hWnd); 326 | PostQuitMessage(0); 327 | break; 328 | 329 | default: /* Passes it on if unproccessed */ 330 | return (DefWindowProc(hWnd, message, wParam, lParam)); 331 | } 332 | return (NULL); 333 | } 334 | 335 | /************************************************************************** 336 | 337 | FUNCTION: cl_setup(HWND) 338 | 339 | PURPOSE: Sets a timer, loads win_sock.dll, establishes a connection 340 | to the server and sends the first buffer. 341 | 342 | **************************************************************************/ 343 | 344 | VOID PASCAL cl_setup(hWnd) 345 | HWND hWnd; 346 | { 347 | int nRc, nLen, nK; 348 | struct hostent far *hp; 349 | struct sockaddr_in server_addr; 350 | 351 | /* Set timer to get control back at reqular intervals. */ 352 | if (SetTimer(hWnd,1,TIMER_INTERVAL,NULL) == 0){ 353 | MessageBox(hWnd, 354 | "Help! Can't set timer.", 355 | "Error", 356 | MB_OK); 357 | return; 358 | } 359 | 360 | /* initialize the index to the screen output buffer */ 361 | nI=0; 362 | 363 | /* create a socket */ 364 | nSd= socket( AF_INET, SOCK_STREAM, 0); 365 | if (nSd < 0) { 366 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"socket call failed, error=%d",errno); 367 | inc_nI(hWnd); 368 | InvalidateRect(hWnd,NULL,TRUE); 369 | cleanup(hWnd); 370 | return; 371 | } 372 | 373 | /* 374 | ** Get IP address from host file. 375 | */ 376 | hp = gethostbyname("win_server_node"); 377 | if (hp == NULL ) { 378 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"win_server_node entry not in hosts file"); 379 | inc_nI(hWnd); 380 | InvalidateRect(hWnd,NULL,TRUE); 381 | cleanup(hWnd); 382 | return; 383 | } 384 | 385 | /* 386 | ** Connect to remote socket at hard coded port. 387 | */ 388 | server_addr.sin_family=AF_INET; 389 | server_addr.sin_port=htons(SRVPORT); 390 | server_addr.sin_addr.s_addr= 391 | *( (unsigned long far *) hp->h_addr_list[0]); 392 | 393 | nRc=connect( nSd, (struct sockaddr far *) &server_addr, 394 | sizeof(server_addr)); 395 | if (nRc <0) { 396 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"Connect failed, error=%d",errno); 397 | inc_nI(hWnd); 398 | InvalidateRect(hWnd,NULL,TRUE); 399 | cleanup(hWnd); 400 | return; 401 | } 402 | 403 | /* initialize the packet */ 404 | for (nK=0; nK= NUM_SENDS) { 479 | cleanup(hWnd); 480 | return; 481 | } 482 | 483 | /* Send the next packet. */ 484 | nLen = send(nSd,sSendbuff,BUFFER_SIZE,0); 485 | if (nLen <0) { 486 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"send failed, error=%d",errno); 487 | inc_nI(hWnd); 488 | InvalidateRect(hWnd,NULL,TRUE); 489 | cleanup(hWnd); 490 | return; 491 | } /* if */ 492 | 493 | /* increment packets count */ 494 | nTotal_packets++; 495 | 496 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"packet %d sent", nTotal_packets); 497 | inc_nI(); 498 | InvalidateRect(hWnd,NULL,TRUE); 499 | } 500 | /**************************************************************************** 501 | 502 | FUNCTION: cleanup(HWND) 503 | 504 | PURPOSE: Kills the timer, closes sockets, frees win_sock.dll 505 | and reinitializes state variables. 506 | 507 | 508 | ****************************************************************************/ 509 | 510 | VOID PASCAL cleanup(hWnd) 511 | HWND hWnd; 512 | { 513 | int nRc, nLen; 514 | 515 | KillTimer(hWnd,1); 516 | 517 | nTest_state=NOT_STARTED; 518 | 519 | /* Send close packet. 520 | * note have to send sSendbuff size packet because the server is designed 521 | * to receive BUFFER_SIZE bytes of data and then check if it is 522 | * a close packet. 523 | */ 524 | sSendbuff[0]=CLOSE; 525 | 526 | /* send close packet */ 527 | nLen = send( nSd, sSendbuff, BUFFER_SIZE, 0); 528 | if (nLen <0) { 529 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"send of close packet failed, error=%d",errno); 530 | inc_nI(hWnd); 531 | InvalidateRect(hWnd,NULL,TRUE); 532 | } 533 | 534 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"End of program. %d packets sent.",nTotal_packets); 535 | inc_nI(); 536 | InvalidateRect(hWnd,NULL,TRUE); 537 | 538 | nRc= close_socket( 539 | nSd, 540 | ); 541 | if (nRc <0) { 542 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"socket closed failed, error=%d",errno); 543 | inc_nI(hWnd); 544 | InvalidateRect(hWnd,NULL,TRUE); 545 | } 546 | nTotal_packets=0; 547 | } 548 | /**************************************************************************** 549 | 550 | FUNCTION: About(HWND, unsigned, WORD, LONG) 551 | 552 | PURPOSE: Processes messages for "About" dialog box 553 | 554 | MESSAGES: 555 | 556 | WM_INITDIALOG - initialize dialog box 557 | WM_COMMAND - Input received 558 | 559 | ****************************************************************************/ 560 | 561 | BOOL FAR PASCAL AboutProc(hDlg, message, wParam, lParam) 562 | HWND hDlg; 563 | unsigned message; 564 | WORD wParam; 565 | LONG lParam; 566 | { 567 | switch (message) { 568 | case WM_INITDIALOG: 569 | return (TRUE); 570 | 571 | case WM_COMMAND: 572 | if (wParam == IDOK 573 | || wParam == IDCANCEL) { 574 | EndDialog(hDlg, TRUE); 575 | return (TRUE); 576 | } 577 | return (TRUE); 578 | } 579 | return (FALSE); 580 | } 581 | /**************************************************************************** 582 | 583 | FUNCTION: inc_nI 584 | 585 | PURPOSE: Increments the line number in the screen output buffer. 586 | 587 | ****************************************************************************/ 588 | VOID PASCAL inc_nI() 589 | { 590 | if (nI 39 | #include 40 | #include 41 | 42 | /* Variables used in windows calls */ 43 | HANDLE hInst; /* current instance */ 44 | short xChar, yChar ; 45 | 46 | /* variables for the screen output buffer */ 47 | char szTextarr[MAXLINES][80]; 48 | short nTextlarr[MAXLINES]; 49 | int nI; 50 | 51 | /* Application state variable. Possible values are: NOT_STARTED, 52 | * WAITING_CONNECTION, and XFER_ACTIVE. 53 | */ 54 | int nTest_state = NOT_STARTED; 55 | 56 | /* variables for sockets activity */ 57 | int nListen_sd, nAcc_sd; 58 | int nTotal_packets; 59 | char sRecvbuff[BUFFER_SIZE]; 60 | 61 | /**************************************************************************** 62 | 63 | FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) 64 | 65 | PURPOSE: calls initialization function, processes message loop 66 | 67 | COMMENTS: 68 | 69 | Windows recognIzes this function by name as the initial entry point 70 | for the program. This function calls the application initialization 71 | routine, if no other instance of the program is running, and always 72 | calls the instance initialization routine. It then executes a message 73 | retrieval and dispatch loop that is the top-level control structure 74 | for the remainder of execution. The loop is terminated when a WM_QUIT 75 | message is received, at which time this function exits the application 76 | instance by returning the value passed by PostQuitMessage(). 77 | 78 | If this function must abort before entering the message loop, it 79 | returns the conventional value NULL. 80 | 81 | ****************************************************************************/ 82 | 83 | int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) 84 | HANDLE hInstance; /* current instance */ 85 | HANDLE hPrevInstance; /* previous instance */ 86 | LPSTR lpCmdLine; /* command line */ 87 | int nCmdShow; /* show-window type (open/icon) */ 88 | { 89 | MSG msg; /* message */ 90 | 91 | if (!hPrevInstance) /* Other instances of app running? */ 92 | if (!InitApplication(hInstance)) /* Initialize shared things */ 93 | return (FALSE); /* Exits if unable to initialize */ 94 | 95 | /* Perform initializations that apply to a specific instance */ 96 | 97 | if (!InitInstance(hInstance, nCmdShow)) 98 | return (FALSE); 99 | 100 | /* Acquire and dispatch messages until a WM_QUIT message is received. */ 101 | 102 | while (GetMessage(&msg, /* message structure */ 103 | NULL, /* handle of window receiving the message */ 104 | NULL, /* lowest message to examine */ 105 | NULL)) /* highest message to examine */ 106 | { 107 | TranslateMessage(&msg); /* Translates virtual key codes */ 108 | DispatchMessage(&msg); /* Dispatches message to window */ 109 | } 110 | 111 | return (msg.wParam); /* Returns the value from PostQuitMessage */ 112 | } 113 | 114 | 115 | /**************************************************************************** 116 | 117 | FUNCTION: InitApplication(HANDLE) 118 | 119 | PURPOSE: Initializes window data and registers window class 120 | 121 | COMMENTS: 122 | 123 | This function is called at initialization time only if no other 124 | instances of the application are running. This function performs 125 | initialization tasks that can be done once for any number of running 126 | instances. 127 | 128 | In this case, we initialize a window class by filling out a data 129 | structure of type WNDCLASS and calling the Windows RegisterClass() 130 | function. Since all instances of this application use the same window 131 | class, we only need to do this when the first instance is initialized. 132 | 133 | 134 | ****************************************************************************/ 135 | 136 | BOOL InitApplication(hInstance) 137 | HANDLE hInstance; /* current instance */ 138 | { 139 | HANDLE hMemory; 140 | PWNDCLASS pWndClass; 141 | BOOL bSuccess; 142 | 143 | hMemory = LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT),sizeof(WNDCLASS)); 144 | pWndClass = (PWNDCLASS) LocalLock(hMemory); 145 | 146 | /* Fill in window class structure with parameters that describe the */ 147 | /* main window. */ 148 | 149 | pWndClass->style = NULL; /* Class style(s). */ 150 | pWndClass->lpfnWndProc = MainWndProc; /* Function to retrieve messages */ 151 | /* windows of this class. */ 152 | pWndClass->cbClsExtra = 0; /* No per-class extra data. */ 153 | pWndClass->cbWndExtra = 0; /* No per-window extra data */ 154 | pWndClass->hInstance = hInstance; /* Application that owns the class. */ 155 | pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION); 156 | pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW); 157 | pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH); 158 | pWndClass->lpszMenuName = "ServerMenu"; /* Name of menu resounRce in .RC file. */ 159 | pWndClass->lpszClassName = "ServerWClass"; /* Name used in call to CreateWindow. */ 160 | 161 | /* Register the window class and return success/failure code. */ 162 | 163 | bSuccess= (RegisterClass(pWndClass)); 164 | 165 | LocalUnlock(hMemory); 166 | LocalFree(hMemory); 167 | return (bSuccess); 168 | 169 | } 170 | 171 | 172 | /**************************************************************************** 173 | 174 | FUNCTION: InitInstance(HANDLE, int) 175 | 176 | PURPOSE: Saves instance handle and creates main window 177 | 178 | COMMENTS: 179 | 180 | This function is called at initialization time for every instance of 181 | this application. This function performs initialization tasks that 182 | cannot be shared by multiple instances. 183 | 184 | In this case, we save the instance handle in a static variable and 185 | create and display the main program window. 186 | 187 | ****************************************************************************/ 188 | 189 | BOOL InitInstance(hInstance, nCmdShow) 190 | HANDLE hInstance; /* Current instance identifier. */ 191 | int nCmdShow; /* Param for first ShowWindow() call. */ 192 | { 193 | HWND hWnd; /* Main window handle. */ 194 | 195 | /* Save the instance handle in static variable, which will be used in */ 196 | /* many subsequence calls from this application to Windows. */ 197 | 198 | hInst = hInstance; 199 | 200 | /* Create a main window for this application instance. */ 201 | 202 | hWnd = CreateWindow( 203 | "ServerWClass", /* See RegisterClass() call. */ 204 | "Server Sample Application", /* Text for window title bar. */ 205 | WS_OVERLAPPEDWINDOW, /* Window style. */ 206 | CW_USEDEFAULT, /* Default horizontal position. */ 207 | CW_USEDEFAULT, /* Default vertical position. */ 208 | CW_USEDEFAULT, /* Default width. */ 209 | CW_USEDEFAULT, /* Default height. */ 210 | NULL, /* Overlapped windows have no parent. */ 211 | NULL, /* Use the window class menu. */ 212 | hInstance, /* This instance owns this window. */ 213 | NULL /* Pointer not needed. */ 214 | ); 215 | 216 | /* If window could not be created, return "failure" */ 217 | 218 | if (!hWnd) 219 | return (FALSE); 220 | 221 | /* Make the window visible; update its client area; and return "success" */ 222 | 223 | ShowWindow(hWnd, nCmdShow); /* Show the window */ 224 | UpdateWindow(hWnd); /* Sends WM_PAINT message */ 225 | return (TRUE); /* Returns the value from PostQuitMessage */ 226 | 227 | } 228 | 229 | /**************************************************************************** 230 | 231 | FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG) 232 | 233 | PURPOSE: Processes messages 234 | 235 | MESSAGES: 236 | 237 | WM_CREATE - create window 238 | WM_COMMAND messages 239 | IDM_SRVSTART - start connection 240 | IDM_ABOUT - display About dialog box 241 | WM_TIMER - set timer interval has expired 242 | WM_DESTROY - destroy window 243 | 244 | ****************************************************************************/ 245 | 246 | long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam) 247 | HWND hWnd; /* window handle */ 248 | unsigned message; /* type of message */ 249 | WORD wParam; /* additional information */ 250 | LONG lParam; /* additional information */ 251 | { 252 | FARPROC lpProc; /* pointer to a function */ 253 | HDC hDC; 254 | TEXTMETRIC tm; 255 | PAINTSTRUCT ps; 256 | 257 | int nJ; 258 | 259 | switch (message) { 260 | 261 | case WM_CREATE: 262 | hDC = GetDC(hWnd); 263 | GetTextMetrics(hDC, &tm); 264 | xChar = tm.tmAveCharWidth; 265 | yChar = tm.tmHeight + tm.tmExternalLeading; 266 | ReleaseDC(hWnd, hDC); 267 | break; 268 | 269 | case WM_PAINT: 270 | /* This program has a simplistic output method. It repaints 271 | * the entire screen for every WM_PAINT message. Each time 272 | * it adds a line of output it calls inc_nI() to increment the 273 | * line number in the output buffer, and it calls InvalidateRect() 274 | * so the screen will be repainted. 275 | */ 276 | if (nI==0) { 277 | return (DefWindowProc(hWnd, message, wParam, lParam)); 278 | } 279 | BeginPaint(hWnd,&ps); 280 | for (nJ=1;nJ<=nI;nJ++) { 281 | TextOut(ps.hdc,xChar,yChar *nJ,&szTextarr[nJ-1][0],nTextlarr[nJ-1]); 282 | } 283 | EndPaint (hWnd, &ps); 284 | break; 285 | 286 | case WM_COMMAND: /* message: command from application menu */ 287 | switch (wParam){ 288 | case IDM_SRVSTART: 289 | if ((nTest_state == XFER_ACTIVE) || (nTest_state==WAITING_CONNECTION)) { 290 | MessageBox(hWnd, 291 | "Already executing sample server test. PLEASE wait.", 292 | "Error", 293 | MB_OK); 294 | } else { 295 | srv_setup(hWnd); 296 | } 297 | break; 298 | 299 | case IDM_ABOUT: 300 | lpProc = MakeProcInstance(AboutProc, hInst); 301 | DialogBox(hInst, "AboutBox", hWnd, lpProc); 302 | FreeProcInstance(lpProc); 303 | break; 304 | } 305 | break; 306 | 307 | case WM_TIMER: /* message: settime expired */ 308 | if (nTest_state==XFER_ACTIVE){ 309 | data_xfer(hWnd); 310 | } 311 | else { 312 | if (nTest_state==WAITING_CONNECTION) { 313 | srv_connect(hWnd); 314 | } 315 | else { 316 | MessageBox(hWnd, 317 | "state error, timer expired and not in XFER_ACTIVE or WAITING_CONNECTION state.", 318 | "Error", 319 | MB_OK); 320 | } 321 | } 322 | break; 323 | case WM_DESTROY: /* message: window being destroyed */ 324 | if ((nTest_state == XFER_ACTIVE) || (nTest_state==WAITING_CONNECTION)) 325 | cleanup(hWnd); 326 | PostQuitMessage(0); 327 | break; 328 | 329 | default: /* Passes it on if unproccessed */ 330 | return (DefWindowProc(hWnd, message, wParam, lParam)); 331 | } 332 | return (NULL); 333 | } 334 | 335 | /************************************************************************** 336 | 337 | FUNCTION: srv_setup(HWND) 338 | 339 | PURPOSE: Set timer, load win_sock.dll, do a listen and set the 340 | application state to WAITING_CONNECTION. 341 | 342 | **************************************************************************/ 343 | 344 | VOID PASCAL srv_setup(hWnd) 345 | HWND hWnd; 346 | 347 | { 348 | int nRc; 349 | struct sockaddr_in server_addr; 350 | 351 | /* Set a timer to get control back at set intervals. */ 352 | if (SetTimer(hWnd,1,TIMER_INTERVAL,NULL) == 0){ 353 | MessageBox(hWnd, 354 | "Help! Can't set timer.", 355 | "Error", 356 | MB_OK); 357 | return; 358 | } 359 | 360 | /* initialized index in screen output buffer */ 361 | nI=0; 362 | 363 | /* 364 | ** create listen socket 365 | */ 366 | nListen_sd= socket( AF_INET, SOCK_STREAM, 0); 367 | if (nListen_sd < 0) { 368 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"socket call failed, error=%d",errno); 369 | inc_nI(hWnd); 370 | InvalidateRect(hWnd,NULL,TRUE); 371 | cleanup(hWnd); 372 | return; 373 | } 374 | 375 | /* 376 | ** bind to wildcard IP address and hard coded port 377 | */ 378 | server_addr.sin_family=AF_INET; 379 | server_addr.sin_port=htons(SRVPORT); 380 | server_addr.sin_addr.s_addr=INADDR_ANY; 381 | nRc=bind( nListen_sd, (struct sockaddr far *) &server_addr, 382 | sizeof(server_addr)); 383 | if (nRc <0) { 384 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"bind call failed, error=%d",errno); 385 | inc_nI(hWnd); 386 | InvalidateRect(hWnd,NULL,TRUE); 387 | cleanup(hWnd); 388 | return; 389 | } 390 | 391 | /* 392 | ** Define listen queue with space for 1 connection 393 | */ 394 | nRc=listen( nListen_sd, 1); 395 | if (nRc <0) { 396 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"listen failed, error=%d",errno); 397 | inc_nI(hWnd); 398 | InvalidateRect(hWnd,NULL,TRUE); 399 | cleanup(hWnd); 400 | return; 401 | } 402 | nTest_state=WAITING_CONNECTION; 403 | } 404 | 405 | /************************************************************************** 406 | 407 | FUNCTION: srv_connect(HWND) 408 | 409 | PURPOSE: Accept the connection and set the application state to 410 | XFER_ACTIVE. 411 | **************************************************************************/ 412 | 413 | VOID PASCAL srv_connect(hWnd) 414 | HWND hWnd; 415 | { 416 | int nRc; 417 | int nfnds, isset_r; 418 | fd_set fdreads; 419 | struct timeval timeout; 420 | 421 | /* see if connection has completed */ 422 | FD_ZERO((fd_set far *) &fdreads); 423 | FD_SET(nListen_sd, (fd_set far *)&fdreads); 424 | nfnds=32; 425 | timeout.tv_sec=0; 426 | timeout.tv_usec=0; 427 | 428 | nRc= select(nfnds,&fdreads,NULL,NULL,&timeout); 429 | if (nRc <0) { 430 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"select call failed, error=%d",errno); 431 | inc_nI(hWnd); 432 | InvalidateRect(hWnd,NULL,TRUE); 433 | cleanup(hWnd); 434 | return; 435 | } 436 | 437 | isset_r=FD_ISSET(nListen_sd, (fd_set far *) &fdreads); 438 | if (isset_r == 0) { 439 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"connect not ready"); 440 | inc_nI(hWnd); 441 | InvalidateRect(hWnd,NULL,TRUE); 442 | return; 443 | } 444 | 445 | /* if connection complete do the accept */ 446 | nAcc_sd=accept( nListen_sd, NULL, NULL); 447 | if (nAcc_sd <0) { 448 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"Accept call failed, error=%d",errno); 449 | inc_nI(hWnd); 450 | InvalidateRect(hWnd,NULL,TRUE); 451 | cleanup(hWnd); 452 | return; 453 | } 454 | 455 | nTest_state=XFER_ACTIVE; 456 | } 457 | 458 | /**************************************************************************** 459 | 460 | FUNCTION: data_xfer(hWnd) 461 | 462 | PURPOSE: Do a send and a receive. Check the first char of the buffer 463 | to see when to quit. 464 | 465 | ****************************************************************************/ 466 | VOID PASCAL data_xfer(hWnd) 467 | HWND hWnd; 468 | { 469 | int nTotal,nLen,nRc; 470 | long lIoctlarg; 471 | 472 | /* check to see if there is anything to receive */ 473 | 474 | nRc = ioctl(nAcc_sd,FIONREAD,(char * far) &lIoctlarg); 475 | if (nRc <0) { 476 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"ioctl call failed, error=%d",errno); 477 | cleanup(hWnd); 478 | return; 479 | } 480 | if (lIoctlarg == 0) { 481 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"Waiting to receive packet"); 482 | inc_nI(hWnd); 483 | InvalidateRect(hWnd,NULL,TRUE); 484 | return; 485 | } 486 | 487 | /* receive */ 488 | 489 | nTotal =0; 490 | do { 491 | nLen = recv( nAcc_sd, &sRecvbuff[nTotal], BUFFER_SIZE-nTotal, 492 | 0); 493 | if ( nLen < 0 ) { 494 | /* break out of do while loop */ 495 | break; 496 | } 497 | nTotal += nLen; 498 | } while ( nTotal < BUFFER_SIZE ); 499 | 500 | if (nLen <0) { 501 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"Recieve called failed, error=%d",errno); 502 | inc_nI(hWnd); 503 | InvalidateRect(hWnd,NULL,TRUE); 504 | cleanup(hWnd); 505 | return; 506 | } /* if*/ 507 | 508 | if (sRecvbuff[0] ==CLOSE) { 509 | cleanup(hWnd); 510 | return; 511 | } 512 | 513 | /* Increment packet count. (Close packet is not counted.) */ 514 | nTotal_packets++; 515 | 516 | /* send the same packet back */ 517 | 518 | nLen = send(nAcc_sd,sRecvbuff,BUFFER_SIZE,0); 519 | if (nLen <0) { 520 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"send call failed, error=%d",errno); 521 | inc_nI(hWnd); 522 | InvalidateRect(hWnd,NULL,TRUE); 523 | cleanup(hWnd); 524 | return; 525 | } /* if */ 526 | 527 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"packet %d received", nTotal_packets); 528 | inc_nI(); 529 | InvalidateRect(hWnd,NULL,TRUE); 530 | } 531 | 532 | /**************************************************************************** 533 | 534 | FUNCTION: cleanup(HWND) 535 | 536 | PURPOSE: Kills the timer, closes sockets, frees win_sock.dll and 537 | reinitializes state variables. 538 | 539 | ****************************************************************************/ 540 | 541 | VOID PASCAL cleanup(hWnd) 542 | HWND hWnd; 543 | { 544 | int nRc; 545 | 546 | KillTimer(hWnd,1); 547 | 548 | nTest_state=NOT_STARTED; 549 | 550 | /* close sockets */ 551 | nRc= close_socket( nListen_sd); 552 | if (nRc <0) { 553 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"close call failed, error= %d",errno); 554 | inc_nI(hWnd); 555 | InvalidateRect(hWnd,NULL,TRUE); 556 | } 557 | 558 | nRc= close_socket( 559 | nAcc_sd, 560 | ); 561 | if (nRc <0) { 562 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"closed call failed, error=%d",errno); 563 | inc_nI(hWnd); 564 | InvalidateRect(hWnd,NULL,TRUE); 565 | } 566 | 567 | nTextlarr[nI]=sprintf(&szTextarr[nI][0],"End of program. %d packets received.",nTotal_packets); 568 | inc_nI(); 569 | InvalidateRect(hWnd,NULL,TRUE); 570 | 571 | nTotal_packets=0; 572 | } 573 | 574 | /**************************************************************************** 575 | 576 | FUNCTION: About(HWND, unsigned, WORD, LONG) 577 | 578 | PURPOSE: Processes messages for "About" dialog box 579 | 580 | MESSAGES: 581 | 582 | WM_INITDIALOG - initialize dialog box 583 | WM_COMMAND - Input received 584 | 585 | ****************************************************************************/ 586 | 587 | BOOL FAR PASCAL AboutProc(hDlg, message, wParam, lParam) 588 | HWND hDlg; 589 | unsigned message; 590 | WORD wParam; 591 | LONG lParam; 592 | { 593 | switch (message) { 594 | case WM_INITDIALOG: 595 | return (TRUE); 596 | 597 | case WM_COMMAND: 598 | if (wParam == IDOK 599 | || wParam == IDCANCEL) { 600 | EndDialog(hDlg, TRUE); 601 | return (TRUE); 602 | } 603 | return (TRUE); 604 | } 605 | return (FALSE); 606 | } 607 | 608 | /**************************************************************************** 609 | 610 | FUNCTION: inc_nI 611 | 612 | PURPOSE: Increments the line number in the screen output buffer. 613 | 614 | ****************************************************************************/ 615 | 616 | VOID PASCAL inc_nI() 617 | { 618 | if (nI 34 | #include 35 | #include 36 | 37 | /* Variables used in windows calls */ 38 | HANDLE hInst; /* current instance */ 39 | short xChar, yChar ; 40 | 41 | /* variables for the screen output buffer */ 42 | char sztextarr[MAXLINES][80]; 43 | short ntextlarr[MAXLINES]; 44 | int nI; 45 | 46 | /* send and receive buffers */ 47 | char ssendbuff[BUFFER_SIZE]; 48 | char srecvbuff[BUFFER_SIZE]; 49 | 50 | /**************************************************************************** 51 | 52 | FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int) 53 | 54 | PURPOSE: calls initialization function, processes message loop 55 | 56 | COMMENTS: 57 | 58 | Windows recognizes this function by name as the initial entry point 59 | for the program. This function calls the application initialization 60 | routine, if no other instance of the program is running, and always 61 | calls the instance initialization routine. It then executes a message 62 | retrieval and dispatch loop that is the top-level control structure 63 | for the remainder of execution. The loop is terminated when a WM_QUIT 64 | message is received, at which time this function exits the application 65 | instance by returning the value passed by PostQuitMessage(). 66 | 67 | If this function must abort before entering the message loop, it 68 | returns the conventional value NULL. 69 | 70 | ****************************************************************************/ 71 | 72 | int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) 73 | HANDLE hInstance; /* current instance */ 74 | HANDLE hPrevInstance; /* previous instance */ 75 | LPSTR lpCmdLine; /* command line */ 76 | int nCmdShow; /* show-window type (open/icon) */ 77 | { 78 | MSG msg; /* message */ 79 | 80 | if (!hPrevInstance) /* Other instances of app running? */ 81 | if (!InitApplication(hInstance)) /* Initialize shared things */ 82 | return (FALSE); /* Exits if unable to initialize */ 83 | 84 | /* Perform initializations that apply to a specific instance */ 85 | 86 | if (!InitInstance(hInstance, nCmdShow)) 87 | return (FALSE); 88 | 89 | /* Acquire and dispatch messages until a WM_QUIT message is received. */ 90 | 91 | while (GetMessage(&msg, /* message structure */ 92 | NULL, /* handle of window receiving the message */ 93 | NULL, /* lowest message to examine */ 94 | NULL)) /* highest message to examine */ 95 | { 96 | TranslateMessage(&msg); /* Translates virtual key codes */ 97 | DispatchMessage(&msg); /* Dispatches message to window */ 98 | } 99 | 100 | return (msg.wParam); /* Returns the value from PostQuitMessage */ 101 | } 102 | 103 | 104 | /**************************************************************************** 105 | 106 | FUNCTION: InitApplication(HANDLE) 107 | 108 | PURPOSE: Initializes window data and registers window class 109 | 110 | COMMENTS: 111 | 112 | This function is called at initialization time only if no other 113 | instances of the application are running. This function performs 114 | initialization tasks that can be done once for any number of running 115 | instances. 116 | 117 | In this case, we initialize a window class by filling out a data 118 | structure of type WNDCLASS and calling the Windows RegisterClass() 119 | function. Since all instances of this application use the same window 120 | class, we only need to do this when the first instance is initialized. 121 | 122 | 123 | ****************************************************************************/ 124 | 125 | BOOL InitApplication(hInstance) 126 | HANDLE hInstance; /* current instance */ 127 | { 128 | HANDLE hMemory; 129 | PWNDCLASS pWndClass; 130 | BOOL bSuccess; 131 | 132 | hMemory = LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT), sizeof(WNDCLASS)); 133 | pWndClass = (PWNDCLASS) LocalLock(hMemory); 134 | 135 | /* Fill in window class structure with parameters that describe the */ 136 | /* main window. */ 137 | 138 | pWndClass->style = NULL; /* Class style(s). */ 139 | pWndClass->lpfnWndProc = MainWndProc; /* Function to retrieve messages */ 140 | /* windows of this class. */ 141 | pWndClass->cbClsExtra = 0; /* No per-class extra data. */ 142 | pWndClass->cbWndExtra = 0; /* No per-window extra data */ 143 | pWndClass->hInstance = hInstance; /* Application that owns the class. */ 144 | pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION); 145 | pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW); 146 | pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH); 147 | pWndClass->lpszMenuName = "UDPMenu"; /* Name of menu resource in .RC file. */ 148 | pWndClass->lpszClassName = "UDPWClass"; /* Name used in call to CreateWindow. */ 149 | 150 | /* Register the window class and return success/failure code. */ 151 | 152 | bSuccess= (RegisterClass(pWndClass)); 153 | 154 | LocalUnlock(hMemory); 155 | LocalFree(hMemory); 156 | return (bSuccess); 157 | 158 | } 159 | 160 | /**************************************************************************** 161 | 162 | FUNCTION: InitInstance(HANDLE, int) 163 | 164 | PURPOSE: Saves instance handle and creates main window 165 | 166 | COMMENTS: 167 | 168 | This function is called at initialization time for every instance of 169 | this application. This function performs initialization tasks that 170 | cannot be shared by multiple instances. 171 | 172 | In this case, we save the instance handle in a static variable and 173 | create and display the main program window. 174 | 175 | ****************************************************************************/ 176 | 177 | BOOL InitInstance(hInstance, nCmdShow) 178 | HANDLE hInstance; /* Current instance identifier. */ 179 | int nCmdShow; /* Param for first ShowWindow() call. */ 180 | { 181 | HWND hWnd; /* Main window handle. */ 182 | 183 | /* Save the instance handle in static variable, which will be used in */ 184 | /* many subsequence calls from this application to Windows. */ 185 | 186 | hInst = hInstance; 187 | 188 | /* Create a main window for this application instance. */ 189 | 190 | hWnd = CreateWindow( 191 | "UDPWClass", /* See RegisterClass() call. */ 192 | "UDP Sample Application", /* Text for window title bar. */ 193 | WS_OVERLAPPEDWINDOW, /* Window style. */ 194 | CW_USEDEFAULT, /* Default horizontal position. */ 195 | CW_USEDEFAULT, /* Default vertical position. */ 196 | CW_USEDEFAULT, /* Default width. */ 197 | CW_USEDEFAULT, /* Default height. */ 198 | NULL, /* Overlapped windows have no parent. */ 199 | NULL, /* Use the window class menu. */ 200 | hInstance, /* This instance owns this window. */ 201 | NULL /* Pointer not needed. */ 202 | ); 203 | 204 | /* If window could not be created, return "failure" */ 205 | 206 | if (!hWnd) 207 | return (FALSE); 208 | 209 | /* Make the window visible; update its client area; and return "success" */ 210 | 211 | ShowWindow(hWnd, nCmdShow); /* Show the window */ 212 | UpdateWindow(hWnd); /* sends WM_PAINT message */ 213 | return (TRUE); /* Returns the value from PostQuitMessage */ 214 | 215 | } 216 | 217 | /**************************************************************************** 218 | 219 | FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG) 220 | 221 | PURPOSE: Processes messages 222 | 223 | MESSAGES: 224 | 225 | WM_CREATE - create window 226 | WM_PAINT - repaints the window 227 | WM_DESTROY - destroy window 228 | 229 | WM_COMMAND messages: 230 | IDM_UDP - do some UDP commands. 231 | 232 | COMMENTS: 233 | 234 | ****************************************************************************/ 235 | 236 | long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam) 237 | HWND hWnd; 238 | unsigned message; 239 | WORD wParam; 240 | LONG lParam; 241 | { 242 | FARPROC lpProcAbout; 243 | HMENU hMenu; 244 | HDC hDC; 245 | PAINTSTRUCT ps; 246 | TEXTMETRIC tm; 247 | 248 | int nJ; 249 | 250 | switch (message) { 251 | 252 | case WM_CREATE: 253 | hDC =GetDC(hWnd); 254 | GetTextMetrics (hDC,&tm); 255 | xChar = tm.tmAveCharWidth; 256 | yChar = tm.tmHeight +tm.tmExternalLeading; 257 | ReleaseDC (hWnd,hDC); 258 | break; 259 | 260 | case WM_PAINT: 261 | /* This program has a simplistic output method. It repaints 262 | * the entire screen for every WM_PAINT message. Each time 263 | * it adds a line of output it calls inc_nI() to increment the 264 | * line number in the output buffer, and it calls InvalidateRect() 265 | * so the screen will be repainted. 266 | */ 267 | if (nI==0) { 268 | return (DefWindowProc(hWnd, message, wParam, lParam)); 269 | } 270 | BeginPaint(hWnd,&ps); 271 | for (nJ=1;nJ<=nI;nJ++) { 272 | TextOut(ps.hdc,xChar,yChar * nJ,&sztextarr[nJ-1][0],ntextlarr[nJ-1]); 273 | } 274 | EndPaint (hWnd, &ps); 275 | break; 276 | 277 | case WM_COMMAND: 278 | switch (wParam) { 279 | case IDM_UDP: 280 | nI=0; 281 | udp_cmds(hWnd); 282 | break; 283 | 284 | case IDM_ABOUT: 285 | lpProcAbout = MakeProcInstance(About, hInst); 286 | DialogBox(hInst, "AboutBox", hWnd, lpProcAbout); 287 | FreeProcInstance(lpProcAbout); 288 | break; 289 | } 290 | break; 291 | 292 | case WM_DESTROY: 293 | PostQuitMessage(NULL); 294 | break; 295 | 296 | default: 297 | return (DefWindowProc(hWnd, message, wParam, lParam)); 298 | } 299 | return (NULL); 300 | } 301 | 302 | /**************************************************************************** 303 | 304 | FUNCTION: udp_cmds(HWND) 305 | 306 | PURPOSE: Creates 2 sockets, binds address and send and receives a 307 | packet. When complete, or if and error occurs cleanup is called. 308 | 309 | ****************************************************************************/ 310 | 311 | VOID PASCAL udp_cmds(hWnd) 312 | HWND hWnd; 313 | 314 | { 315 | int nJ; 316 | int nFromLen; 317 | int nSd1,nSd2; 318 | int nRc, nLen; 319 | struct hostent far *hp; 320 | struct sockaddr_in nSd1_addr, nSd2_addr, from; 321 | char far * szIP; 322 | 323 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"Starting UDP sample application"); 324 | inc_nI(); 325 | InvalidateRect(hWnd,NULL,TRUE); 326 | 327 | /* create nSd1 socket */ 328 | nSd1= socket( AF_INET, SOCK_DGRAM, 0); 329 | if (nSd1 < 0) { 330 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"1st socket call failed, error=%d ",errno); 331 | inc_nI(); 332 | InvalidateRect(hWnd,NULL,TRUE); 333 | return; 334 | } 335 | 336 | /* create nSd2 socket */ 337 | nSd2= socket( AF_INET, SOCK_DGRAM, 0); 338 | if (nSd2 < 0) { 339 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"2nd socket call failed, error=%d",errno); 340 | inc_nI(); 341 | InvalidateRect(hWnd,NULL,TRUE); 342 | cleanup(hWnd, nSd1, nSd2); 343 | return; 344 | } 345 | 346 | /* get IP address of local node */ 347 | hp = gethostbyname( "local_node"); 348 | if (hp ==NULL) { 349 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"can't continue, 'local_node' not found in hosts table"); 350 | inc_nI(); 351 | InvalidateRect(hWnd,NULL,TRUE); 352 | cleanup(hWnd, nSd1, nSd2); 353 | return; 354 | } 355 | 356 | /* bind both sockets to hard coded ports */ 357 | nSd1_addr.sin_family=AF_INET; 358 | nSd1_addr.sin_port=htons(PORT1); 359 | nSd1_addr.sin_addr.s_addr= 360 | *( (unsigned long far *) hp->h_addr_list[0]); 361 | nRc=bind( nSd1, (struct sockaddr far *) &nSd1_addr, 362 | sizeof(nSd1_addr)); 363 | if (nRc <0) { 364 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"bind of socket nSd1=%d failed, error=%d",nSd1,errno); 365 | inc_nI(); 366 | InvalidateRect(hWnd,NULL,TRUE); 367 | cleanup(hWnd, nSd1, nSd2); 368 | return; 369 | } 370 | 371 | nSd2_addr.sin_family=AF_INET; 372 | nSd2_addr.sin_port=htons(PORT2); 373 | nSd2_addr.sin_addr.s_addr = 374 | *( (unsigned long far *) hp->h_addr_list[0]); 375 | nRc=bind( nSd2, (struct sockaddr far *) &nSd2_addr, 376 | sizeof(nSd2_addr)); 377 | if (nRc <0) { 378 | ntextlarr[nI]=sprintf(&sztextarr[nI][0],"bind of socket nSd2=%d failed, error=%d",nSd1,errno); 379 | inc_nI(); 380 | InvalidateRect(hWnd,NULL,TRUE); 381 | cleanup(hWnd, nSd1, nSd2); 382 | return; 383 | } 384 | 385 | /* initialize buffer */ 386 | for (nJ=0; nJ