CLIENT.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /****************************************************************************
  2. *  dgrecv.c -- sample program demonstrating NWLink.
  3. *
  4. *       Microsoft Developer Support
  5. *       Copyright 1992 - 1997 Microsoft Corporation
  6. *
  7. *  This program is a simple example of using SPX connect.
  8. *
  9. ****************************************************************************/
  10. #include <windows.h>
  11. #include <winsock.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <malloc.h>
  16. #include "wshisotp.h"
  17. typedef struct tag_error_struct{
  18.     int     errnum;
  19.     LPSTR   errstr;
  20. } ERROR_STRUCT;
  21. SOCKADDR_TP addr;
  22. SOCKADDR_TP caddr;
  23. UCHAR ch = 0;
  24. char LocalNetworkAddress[22];
  25. char LocalNetworkAddressLength;
  26. short   LocalTsel;
  27. char RemoteNetworkAddress[22];
  28. char RemoteNetworkAddressLength;
  29. short   RemoteTsel;
  30. int     verbose = 1;
  31. int     Socket_Type = SOCK_SEQPACKET;
  32. int     Protocol = ISOPROTO_TP4;
  33. int     Local_Address_Family = AF_ISO;
  34. int     Remote_Address_Family = AF_ISO;
  35. int     Backlog = 1;
  36. int     No_Broadcast = 0;
  37. int     No_Loop = 0;
  38. int     Sleep_Time = 1000;
  39. int     Send_Length = 100;
  40. int     Receive_Length = 200;
  41. int     Local_Packet_Type = 0;
  42. #define WSAERRGAP1 28
  43. #define WSAERRGAP2 19
  44. char msg_no_error[19] =      "No error occurred!";
  45. char msg_unknown_error[14] = "Unknown error";
  46. ERROR_STRUCT errlist[] = {
  47.     {WSAEINTR,           "WSAEINTR - Interrupted"},
  48.     {WSAEBADF,           "WSAEBADF - Bad file number"},
  49.     {WSAEFAULT,          "WSAEFAULT - Bad address"},
  50.     {WSAEINVAL,          "WSAEINVAL - Invalid argument"},
  51.     {WSAEMFILE,          "WSAEMFILE - Too many open files"},
  52. /*
  53. *    Windows Sockets definitions of regular Berkeley error constants
  54. */
  55.     {WSAEWOULDBLOCK,     "WSAEWOULDBLOCK - Socket marked as non-blocking"},
  56.     {WSAEINPROGRESS,     "WSAEINPROGRESS - Blocking call in progress"},
  57.     {WSAEALREADY,        "WSAEALREADY - Command already completed"},
  58.     {WSAENOTSOCK,        "WSAENOTSOCK - Descriptor is not a socket"},
  59.     {WSAEDESTADDRREQ,    "WSAEDESTADDRREQ - Destination address required"},
  60.     {WSAEMSGSIZE,        "WSAEMSGSIZE - Data size too large"},
  61.     {WSAEPROTOTYPE,      "WSAEPROTOTYPE - Protocol is of wrong type for this socket"},
  62.     {WSAENOPROTOOPT,     "WSAENOPROTOOPT - Protocol option not supported for this socket type"},
  63.     {WSAEPROTONOSUPPORT, "WSAEPROTONOSUPPORT - Protocol is not supported"},
  64.     {WSAESOCKTNOSUPPORT, "WSAESOCKTNOSUPPORT - Socket type not supported by this address family"},
  65.     {WSAEOPNOTSUPP,      "WSAEOPNOTSUPP - Option not supported"},
  66.     {WSAEPFNOSUPPORT,    "WSAEPFNOSUPPORT - "},
  67.     {WSAEAFNOSUPPORT,    "WSAEAFNOSUPPORT - Address family not supported by this protocol"},
  68.     {WSAEADDRINUSE,      "WSAEADDRINUSE - Address is in use"},
  69.     {WSAEADDRNOTAVAIL,   "WSAEADDRNOTAVAIL - Address not available from local machine"},
  70.     {WSAENETDOWN,        "WSAENETDOWN - Network subsystem is down"},
  71.     {WSAENETUNREACH,     "WSAENETUNREACH - Network cannot be reached"},
  72.     {WSAENETRESET,       "WSAENETRESET - Connection has been dropped"},
  73.     {WSAECONNABORTED,    "WSAECONNABORTED - "},
  74.     {WSAECONNRESET,      "WSAECONNRESET - "},
  75.     {WSAENOBUFS,         "WSAENOBUFS - No buffer space available"},
  76.     {WSAEISCONN,         "WSAEISCONN - Socket is already connected"},
  77.     {WSAENOTCONN,        "WSAENOTCONN - Socket is not connected"},
  78.     {WSAESHUTDOWN,       "WSAESHUTDOWN - Socket has been shut down"},
  79.     {WSAETOOMANYREFS,    "WSAETOOMANYREFS - "},
  80.     {WSAETIMEDOUT,       "WSAETIMEDOUT - Command timed out"},
  81.     {WSAECONNREFUSED,    "WSAECONNREFUSED - Connection refused"},
  82.     {WSAELOOP,           "WSAELOOP - "},
  83.     {WSAENAMETOOLONG,    "WSAENAMETOOLONG - "},
  84.     {WSAEHOSTDOWN,       "WSAEHOSTDOWN - "},
  85.     {WSAEHOSTUNREACH,    "WSAEHOSTUNREACH - "},
  86.     {WSAENOTEMPTY,       "WSAENOTEMPTY - "},
  87.     {WSAEPROCLIM,        "WSAEPROCLIM - "},
  88.     {WSAEUSERS,          "WSAEUSERS - "},
  89.     {WSAEDQUOT,          "WSAEDQUOT - "},
  90.     {WSAESTALE,          "WSAESTALE - "},
  91.     {WSAEREMOTE,         "WSAEREMOTE - "},
  92. /*
  93. *    Extended Windows Sockets error constant definitions
  94. */
  95.     {WSASYSNOTREADY,     "WSASYSNOTREADY - Network subsystem not ready"},
  96.     {WSAVERNOTSUPPORTED, "WSAVERNOTSUPPORTED - Version not supported"},
  97.     {WSANOTINITIALISED,  "WSANOTINITIALISED - WSAStartup() has not been successfully called"},
  98. /*
  99. *    Other error constants.
  100. */
  101.     {WSAHOST_NOT_FOUND,  "WSAHOST_NOT_FOUND - Host not found"},
  102.     {WSATRY_AGAIN,       "WSATRY_AGAIN - Host not found or SERVERFAIL"},
  103.     {WSANO_RECOVERY,     "WSANO_RECOVERY - Non-recoverable error"},
  104.     {WSANO_DATA,         "WSANO_DATA - (or WSANO_ADDRESS) - No data record of requested type"},
  105.     {-1,                 NULL}
  106. };
  107. /*
  108. *   Function Prototypes
  109. */
  110. extern int main(int, char **);
  111. extern int net_init(SOCKET *);
  112. extern int make_connection(SOCKET);
  113. extern int do_send_receive(SOCKET);
  114. extern void dos_net_perror(LPSTR );
  115. extern LPCSTR dos_net_strerror(LPSTR );
  116. extern LPCSTR get_error_text(int );
  117. /****************************************************************************
  118. *
  119. *    FUNCTION:  main( int argc, char **argv )
  120. *
  121. *    PURPOSE:   This is the main entry for the program
  122. *
  123. *
  124. *    ARGUMENTS: argc = Number of arguments
  125. *               argv = Array of ptrs to cmd line args
  126. *
  127. *
  128. *        RETURNS:   Exit code for the program
  129. *
  130. ****************************************************************************/
  131. int main(int argc, char **argv)
  132. {
  133.     SOCKET s;
  134.    /*
  135.    ** Read Local & Remote Transport Address fields from user
  136.    */
  137.    printf("LocalNetworkAddress(max. 20 chars) : ");
  138.    scanf("%s", &LocalNetworkAddress[0]);
  139.    printf("LocalTsel : ");
  140.    scanf("%d", &LocalTsel);
  141.    LocalNetworkAddressLength = strlen(LocalNetworkAddress) ;
  142.    printf("RemoteNetworkAddress(max. 20 chars) : ");
  143.    scanf("%s", &RemoteNetworkAddress[0]);
  144.    printf("RemoteTsel : ");
  145.    scanf("%d", &RemoteTsel);
  146.    RemoteNetworkAddressLength = strlen(RemoteNetworkAddress) ;
  147. printf("local Tsel(%d) Net_length(%d) Net(%s)n",
  148.         LocalTsel, LocalNetworkAddressLength, LocalNetworkAddress);
  149. printf("Remote Tsel(%d) Net_length(%d) Net(%s)n",
  150.         RemoteTsel, RemoteNetworkAddressLength, RemoteNetworkAddress);
  151.     /*
  152.     *   Initialize the network and set up the socket
  153.     */
  154.     if (net_init(&s))
  155.         return 1;
  156.     /*
  157.     *   Try to connect to our server
  158.     */
  159.     if (make_connection(s))
  160.         return 1;
  161.     /*
  162.     *   Send/receive data to/from server
  163.     */
  164.     do_send_receive(s);
  165.     /*
  166.     *   All done - close up
  167.     */
  168.     if (verbose)
  169.         printf("calling closesocket(socket = %d)n", s);
  170.     closesocket(s);
  171.     return 0;
  172. }
  173. /****************************************************************************
  174. *
  175. *    FUNCTION:  net_init( SOCKET *skt )
  176. *
  177. *    PURPOSE:   Initializes the WinSock stuff and sets up our socket.
  178. *
  179. *
  180. *    ARGUMENTS: SOCKET * => struct to fill in with opened socket.
  181. *
  182. *        RETURNS:   0 if ok
  183. *                               1 if error
  184. *
  185. ****************************************************************************/
  186. int net_init(SOCKET *skt)
  187. {
  188.     SOCKET s;
  189.     int rc, addrlen;
  190.     int reuse = 1;
  191.     WSADATA wsdata;
  192.     WORD    wVersionRequested;
  193.     wVersionRequested = MAKEWORD(1,1);
  194.     /*
  195.     *   Register with the socket library
  196.     */
  197.     rc = WSAStartup(wVersionRequested, &wsdata);
  198.     if (verbose)
  199.         printf("WSAStartup returned 0x%Xn", rc);
  200.     if (rc) {
  201.         printf("WSAStartup failed: error = %dn", rc);
  202.         return 1;
  203.     }
  204.     /*
  205.     *   Open a STREAMING socket
  206.     */
  207.     s = socket(Local_Address_Family, Socket_Type, Protocol);
  208.     if (verbose)
  209.         printf("socket() returned 0x%X (%d)n", s, s);
  210.     if (s == INVALID_SOCKET) {
  211.         printf("socket call failed");
  212.         return 1;
  213.     }
  214.     /*
  215.     *   Bind to any address
  216.     */
  217.     ISO_SET_TP_ADDR(&addr, &LocalTsel, sizeof(LocalTsel),
  218.                         LocalNetworkAddress, LocalNetworkAddressLength);
  219.     rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char FAR *)&reuse, sizeof(int));
  220.     if (rc == SOCKET_ERROR) {
  221.         dos_net_perror("setsockopt call failed");
  222.         return 1;
  223.     }
  224.     rc = bind(s, (const struct sockaddr *)&addr, sizeof(SOCKADDR_TP));
  225.     if (verbose)
  226.         printf("bind() returned 0x%Xn", rc);
  227.     if (rc == SOCKET_ERROR) {
  228.         dos_net_perror("bind call failed");
  229.         return 1;
  230.     }
  231.     if (verbose)
  232.         printf("calling getsockname(socket = %d)n", s);
  233.     addrlen = sizeof(SOCKADDR_TP);
  234.     rc = getsockname(s, (struct sockaddr *) &addr, &addrlen);
  235.     if (verbose)
  236.         printf("getsockname() returned 0x%Xn", rc);
  237.     if (rc == SOCKET_ERROR) {
  238.         printf("Error binding to socket");
  239.         closesocket(s);
  240.         return 1;
  241.     }
  242. /*
  243.     if (verbose) {
  244.         printf("addrlen = %dn", addrlen);
  245.         print_netaddr(addr.sa_netnum, "Bound address = ", "n");
  246.     }
  247. */
  248.     /*
  249.     *   Build the address of the node to connect to
  250.     */
  251. ISO_SET_TP_ADDR(&caddr, &RemoteTsel, sizeof(RemoteTsel),
  252.                         RemoteNetworkAddress, RemoteNetworkAddressLength);
  253. /*
  254.     caddr.sa_family = Remote_Address_Family;
  255.     caddr.addr_type = HIERARCHICAL;
  256.     caddr.taddr_len = RemoteNetworkAddressLength + RemoteTselLength;
  257.     caddr.tsel_len = RemoteTselLength;
  258.     memcpy(&caddr.addr, RemoteTsel, RemoteTselLength);
  259.     memcpy(&caddr.addr[RemoteTselLength],
  260.                 RemoteNetworkAddress, RemoteNetworkAddressLength);
  261. */
  262.     /*
  263.     *   Set up socket for return
  264.     */
  265.     *skt = s;
  266.     return 0;
  267. }
  268. /****************************************************************************
  269. *
  270. *    FUNCTION:  make_connection( SOCKET s )
  271. *
  272. *    PURPOSE:   Establishes a connection with our server.
  273. *
  274. *    ARGUMENTS: SOCKET socket to use for connection
  275. *
  276. *        RETURNS:   0 if ok
  277. *                               1 if error
  278. *
  279. ****************************************************************************/
  280. int make_connection(SOCKET s)
  281. {
  282.     int rc, addrlen;
  283.     /*
  284.     *   Connect
  285.     */
  286.     if (verbose)
  287.         printf("calling connect(socket = %d)n", s);
  288.     rc = connect(s, (const struct sockaddr FAR *)&caddr, sizeof(SOCKADDR_TP));
  289.     if (verbose)
  290.         printf("connect() returned 0x%Xn", rc);
  291.     if (rc == SOCKET_ERROR) {
  292.         dos_net_perror("connect call failed");
  293.         return 1;
  294.     }
  295.     printf("Connect OKn");
  296.     /*
  297.     *   Print out address we connected to
  298.     */
  299.     if (verbose)
  300.         printf("calling getpeername(socket = %d)n", s);
  301.     addrlen = sizeof(SOCKADDR_TP);
  302.     rc = getpeername(s, (struct sockaddr *) &caddr, &addrlen);
  303.     if (verbose)
  304.         printf("getpeername() returned 0x%Xn", rc);
  305. /*
  306.     if (verbose) {
  307.         printf("addrlen = %dn", addrlen);
  308.         print_netaddr(caddr.sa_netnum, "Remote Address = ", "n");
  309.     }
  310. */
  311.     return 0;
  312. }
  313. /****************************************************************************
  314. *
  315. *    FUNCTION:  do_send_receive( SOCKET *s )
  316. *
  317. *    PURPOSE:   Alternately sends/receives data to/from the server.
  318. *
  319. *    ARGUMENTS: SOCKET socket to transmit on
  320. *
  321. *        RETURNS:   0 if ok
  322. *                               1 if error
  323. *
  324. ****************************************************************************/
  325. int do_send_receive(SOCKET s)
  326. {
  327.     int rc, errflag = 0;
  328.     int sndpkts = 0, rcvpkts = 0;
  329.     LPSTR sendbuf;
  330.     /*
  331.     *   Allocate a send buffer
  332.     */
  333.     if (verbose)
  334.         printf("Allocating %d bytes for send buffer n");
  335.     sendbuf = malloc(Send_Length);
  336.     if (!sendbuf) {
  337.         printf("Error allocating %d bytes for send buffern");
  338.         return 1;
  339.     }
  340.     /*
  341.     *   Send data and recv it back
  342.     */
  343.     while (1) {
  344.         /*
  345.         *   Fill the buffer with our current character
  346.         */
  347.         memset(sendbuf, ch, Send_Length);
  348.         /*
  349.         *   Send data
  350.         */
  351.         if (verbose)
  352.             printf("calling send(socket = %d, length = %d)n", s, Send_Length);
  353.         rc = send(s, sendbuf, Send_Length, 0);
  354.         if (verbose)
  355.             printf("send() returned 0x%Xn", rc);
  356.         if (rc == SOCKET_ERROR) {
  357.             printf("nsend() call failed");
  358.             errflag++;
  359.             break;
  360.         }
  361.         if (verbose)
  362.             printf("Sent packet %d: sent %d bytesn", sndpkts++, rc);
  363.         else
  364.             printf("rSent packet %d: sent %d bytes... ", sndpkts++, rc);
  365.         /*
  366.         *   Receive the data back
  367.         */
  368. /*
  369.         if (verbose)
  370.             printf("calling recv(socket = %d, length = %d)n", s, Send_Length);
  371.         rc = recv(s, sendbuf, Send_Length, 0);
  372.         if (verbose)
  373.             printf("recv() returned %dn", rc);
  374.         if (rc == SOCKET_ERROR) {
  375.             printf("nrecv() call failed");
  376.             errflag++;
  377.             break;
  378.         }
  379.         if (!rc) {
  380.             printf("connection has been lostn");
  381.             break;
  382.         }
  383.         printf("Received %d bytes", rc);
  384. */
  385.         if (verbose)
  386.             printf("n");
  387.         /*
  388.         *   See if our buffer has the same data in it
  389.         */
  390.         rc = mem_check(sendbuf, ch++, Send_Length);
  391.         if (rc)
  392.             printf("Data compare error: packet = %d, offset = %dn", (sndpkts-1), rc);
  393.         else if (verbose)
  394.             printf("Data compares okayn");
  395.         /*
  396.         *   If we are to send just 1, break out
  397.         */
  398.         if (No_Loop)
  399.             break;
  400.         /*
  401.         *   Pause a little while (don't trash the network)
  402.         Sleep(Sleep_Time);
  403.         */
  404.     }
  405.     if (verbose)
  406.         printf("nFreeing send buffern");
  407.     free(sendbuf);
  408.     return errflag;
  409. }
  410. /****************************************************************************
  411. *
  412. *    FUNCTION:  mem_check( LPSTR p, UCHAR ch, int len)
  413. *
  414. *    PURPOSE:   Makes sure that a buffer is filled with only the character
  415. *                   specified.
  416. *
  417. *    ARGUMENTS: LPSTR   => buffer to scan
  418. *               char    character to check for
  419. *               int     length of buffer to check
  420. *
  421. *        RETURNS:   0 if buffer has only the specified character
  422. *                               offset to non-matching character if found
  423. *
  424. ************************************************************************/
  425. int mem_check(LPSTR p, UCHAR ch, int len)
  426. {
  427.     int buflen;
  428.     buflen = len;
  429.     while (len--) {
  430.         if ((UCHAR)*p++ != ch) {
  431.             return (buflen - len);
  432.         }
  433.     }
  434.     return 0;
  435. }
  436. void dos_net_perror(LPSTR p)
  437. {
  438.     printf(dos_net_strerror(p));
  439.     printf("n");
  440.     return;
  441. }
  442. LPCSTR dos_net_strerror(LPSTR p)
  443. {
  444.     int error = 0;
  445.     static char return_string[256];
  446.     /*
  447.     *   Get the error number from the system
  448.     */
  449.     error = h_errno;
  450.     /*
  451.     *   Build the string to return
  452.     */
  453.     sprintf(return_string, "%s :(%d)%s", p, error, get_error_text(error));
  454.     return (LPSTR)return_string;
  455. }
  456. LPCSTR get_error_text(int error)
  457. {
  458.     int search = 0;
  459.     /*
  460.     *   No error
  461.     */
  462.     if (!error)
  463.         return (LPCSTR)msg_no_error;
  464.     /*
  465.     *   Search through our array of error number / string pairs
  466.     *   until we find a matching error number or get to the end
  467.     *   of our list.  If we found a matching error number,
  468.     *   return a LPSTR to the corresponding string.
  469.     */
  470.     while (errlist[search].errstr) {
  471.         if (error == errlist[search].errnum)
  472.             return errlist[search].errstr;
  473.         search++;
  474.     }
  475.     /*
  476.     * If we didn't have the error in our list, return unkown
  477.     */
  478.     return (LPCSTR)msg_unknown_error;
  479. }