home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winsock / tp4 / server.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-09  |  10.2 KB  |  440 lines

  1. /****************************************************************************\
  2. *  listen.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 opening a SPX socket,
  8. *  binding to the socket, and listening for a connection.
  9. *
  10. ****************************************************************************/
  11. #include <windows.h>
  12. #include <winsock.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <malloc.h>
  17. #include "wshisotp.h"
  18.  
  19. /*
  20. *   Sockaddr structures
  21. */
  22.  
  23. SOCKADDR_TP addr;
  24. SOCKADDR_TP baddr;
  25. SOCKADDR_TP saddr;
  26.  
  27. /*
  28. *   Function Prototypes
  29. */
  30.  
  31. extern int main(int, char **);
  32. extern int net_init(SOCKET *);
  33. extern int do_listen(SOCKET);
  34. extern int wait_for_connection(SOCKET, SOCKET *);
  35. extern int do_recv_send(SOCKET);
  36.  
  37. char LocalNetworkAddress[22];
  38. char LocalNetworkAddressLength;
  39. short   LocalTsel;
  40.  
  41. int     verbose = 1;
  42. int     Socket_Type = SOCK_SEQPACKET;
  43. int     Protocol = ISOPROTO_TP4;
  44. int     Local_Address_Family = AF_ISO;
  45. int     Remote_Address_Family = AF_ISO;
  46. int     Backlog = 1;
  47. int     No_Broadcast = 0;
  48. int     No_Loop = 0;
  49. int     Sleep_Time = 1000;
  50. int     Send_Length = 100;
  51. int     Receive_Length = 200;
  52. int     Local_Packet_Type = 0;
  53.  
  54. /****************************************************************************
  55. *
  56. *    FUNCTION:  main( int argc, char **argv )
  57. *
  58. *    PURPOSE:   This is the main entry for the program
  59. *
  60. *
  61. *    ARGUMENTS: argc = Number of arguments
  62. *               argv = Array of ptrs to cmd line args
  63. *
  64. *
  65. *        RETURNS:   Exit code for the program
  66. *
  67. *\***************************************************************************/
  68. int main(int argc, char **argv)
  69. {
  70.     SOCKET s, s2;
  71.  
  72.    /*
  73.    ** Read Local Transport Address fields from user
  74.    */
  75.    printf("LocalNetworkAddress(max. 20 chars) : ");
  76.    scanf("%s", &LocalNetworkAddress[0]);
  77.    printf("LocalTsel : ");
  78.    scanf("%d", &LocalTsel);
  79.  
  80.    LocalNetworkAddressLength = strlen(LocalNetworkAddress) ;
  81.  
  82. printf("Local Tsel(%d) Net_length(%d) Net(%s)\n",
  83.         LocalTsel, LocalNetworkAddressLength, LocalNetworkAddress);
  84.  
  85.  
  86.     /*
  87.     *   Initialize the network and set up our socket
  88.     */
  89.  
  90.     if (net_init(&s))
  91.         return 1;
  92.  
  93.     if (verbose)
  94.         printf("calling do_listen\n");
  95.  
  96.     /*
  97.     *   Go listen for a call
  98.     */
  99.  
  100.     if (do_listen(s))
  101.         return 1;
  102.  
  103.     /*
  104.     *   Then wait for a connection
  105.     */
  106.  
  107.     if (verbose)
  108.         printf("calling wait_for_connection\n");
  109.  
  110.     if (wait_for_connection(s, &s2))
  111.         return 1;
  112.  
  113.     /*
  114.     *   Receive data then send it back
  115.     */
  116.  
  117.     if (verbose)
  118.         printf("calling do_recv_send\n");
  119.  
  120.     if (do_recv_send(s2))
  121.         return 1;
  122.  
  123.     /*
  124.     *   All done
  125.     */
  126.  
  127.     if (verbose)
  128.         printf("closing both sockets\n");
  129.  
  130.     closesocket(s2);
  131.     closesocket(s);
  132.  
  133.     return 0;
  134. }
  135.  
  136. /****************************************************************************
  137. *
  138. *    FUNCTION:  net_init( SOCKET *skt )
  139. *
  140. *    PURPOSE:   Initializes the WinSock stuff and sets up our socket.
  141. *
  142. *
  143. *    ARGUMENTS: SOCKET * => struct to receive our socket info
  144. *
  145. *        RETURNS:   0 if ok
  146. *                               1 if error
  147. *
  148. *\***************************************************************************/
  149. int net_init(SOCKET *skt)
  150. {
  151.     int i, rc, addrlen;
  152.     WSADATA wsdata;
  153.     SOCKET s;
  154.     char *adr;
  155.  
  156.     /*
  157.     *   Initialize with the WINSOCK library
  158.     */
  159.  
  160.     if (verbose)
  161.         printf("calling WSAStartup(), ");
  162.  
  163.     rc = WSAStartup(MAKEWORD(1,1), &wsdata);
  164.  
  165.     if (verbose)
  166.         printf("return = 0x%X, (%d)\n", rc, rc);
  167.  
  168.     if (rc) {
  169.         printf("WSAStartup failed: error code = %d\n", rc);
  170.         return 1;
  171.     }
  172.  
  173.  
  174.     /*
  175.     *   Open a STREAM socket with SPX
  176.     */
  177.  
  178.     if (verbose)
  179.         printf("calling socket(addresss family = %d, socket type = %d, protocol = %d)\n", Local_Address_Family, Socket_Type, Protocol);
  180.  
  181.     s = socket(Local_Address_Family, Socket_Type, Protocol);
  182.  
  183.  
  184.     if (verbose)
  185.         printf("socket() returned 0x%X (%d)\n", s, s);
  186.  
  187.     if (s == INVALID_SOCKET) {
  188.         printf("Socket call failed\n");
  189.         exit(1);
  190.     }
  191.  
  192.     /*
  193.     *   Bind to a socket.  We want to bind to a well known
  194.     *   socket so that who ever calls us will be able to.
  195.     */
  196. ISO_SET_TP_ADDR(&addr, &LocalTsel, sizeof(LocalTsel),
  197.                         LocalNetworkAddress, LocalNetworkAddressLength);
  198.  
  199. /*
  200.     addr.sa_family = Local_Address_Family;
  201.     addr.addr_type = HIERARCHICAL;
  202.     addr.taddr_len = LocalNetworkAddressLength + LocalTselLength;
  203.     addr.tsel_len = LocalTselLength;
  204.     memcpy(&addr.addr, LocalTsel, LocalTselLength);
  205.     memcpy(&addr.addr[LocalTselLength],
  206.                 LocalNetworkAddress, LocalNetworkAddressLength);
  207. */
  208.  
  209.     if (verbose) {
  210.         printf("calling bind(socket = %d): \n  ", s);
  211.     }
  212.  
  213.     rc = bind(s, (const struct sockaddr *) &addr, sizeof(SOCKADDR_TP));
  214.  
  215.     if (verbose)
  216.         printf("bind() returned 0x%X (%d)\n", rc, rc);
  217.  
  218.     if (rc == SOCKET_ERROR) {
  219.         printf("Error binding to socket\n");
  220.         closesocket(s);
  221.         return 1;
  222.     }
  223.  
  224.     if (verbose)
  225.         printf("calling getsockname(socket = %d), ", s);
  226.  
  227.     /*
  228.     *   Get the address we bound to and print it out
  229.     */
  230.  
  231.     addrlen = sizeof(SOCKADDR_TP);
  232.     rc = getsockname(s, (struct sockaddr *) &baddr, &addrlen);
  233.  
  234.     if (verbose)
  235.         printf("return = 0x%X (%d)\n", rc, rc);
  236.  
  237.     if (rc == SOCKET_ERROR) {
  238.         printf("Error getting socket name");
  239.         closesocket(s);
  240.         return 1;
  241.     }
  242.  
  243.     /*
  244.      *   Print out the network address
  245.      */
  246.     if (verbose) {
  247.         adr = (char *)&baddr;
  248.         printf("len(%d) addr : ", addrlen);
  249.         for ( i = 0; i < addrlen; i++)
  250.                 printf(" %x ", *(adr + i));
  251.     }
  252.  
  253.     *skt = s;
  254.  
  255.     return 0;
  256. }
  257.  
  258. /****************************************************************************
  259. *
  260. *    FUNCTION:  do_listen( SOCKET s )
  261. *
  262. *    PURPOSE:   Sets the socket up for listening.
  263. *
  264. *    ARGUMENTS: SOCKET socket to listen on
  265. *
  266. *        RETURNS:   0 if ok
  267. *                               1 if error
  268. *
  269. *\***************************************************************************/
  270. int do_listen(SOCKET s)
  271. {
  272.     int rc;
  273.  
  274.     /*
  275.     *   Enable this socket as a listen socket that can
  276.     *   take <Backlog> connection indication(s) at a time.
  277.     */
  278.  
  279.     if (verbose)
  280.         printf("calling listen(socket = %d, backlog = %d), ", s, Backlog);
  281.  
  282.     rc = listen(s, Backlog);
  283.  
  284.     if (verbose)
  285.         printf("return = 0x%X (%d)\n", rc, rc);
  286.  
  287.     if (rc == SOCKET_ERROR) {
  288.         printf("listen call failed");
  289.         closesocket(s);
  290.         return 1;
  291.     }
  292.  
  293.     /*
  294.     *   Wait for a connection and get the connecting socket
  295.     */
  296.  
  297.     return 0;
  298. }
  299.  
  300. /****************************************************************************
  301. *
  302. *    FUNCTION:  wait_for_connection( SOCKET s, SOCKET *callsock )
  303. *
  304. *    PURPOSE:   Waits for someone to connect.
  305. *
  306. *    ARGUMENTS: SOCKET socket we are listening on
  307. *                               SOCKET * => area to store client socket info after
  308. *                                           connect
  309. *
  310. *        RETURNS:   0 if ok
  311. *                               1 if error
  312. *
  313. *\***************************************************************************/
  314. int wait_for_connection(SOCKET s, SOCKET *callsock)
  315. {
  316.     SOCKET s2;
  317.     int addrlen = sizeof(SOCKADDR_TP);
  318.  
  319.     /*
  320.     *   Go wait for somebody to connect
  321.     */
  322.  
  323.     if (verbose)
  324.         printf("calling accept(socket = %d), ", s);
  325.     else
  326.         printf("Waiting for call...\n");
  327.  
  328.     s2 = accept(s, (struct sockaddr *) &saddr, &addrlen);
  329.  
  330.     if (verbose)
  331.         printf("return (socket) = 0x%X (%d)\n", s2, s2);
  332.  
  333.     if (s2 == INVALID_SOCKET) {
  334.         printf("accept call failed");
  335.         closesocket(s);
  336.         return 1;
  337.     }
  338.  
  339.     /*
  340.     *   Print out who connected to us
  341.  
  342.     if (verbose) {
  343.         printf("addrlen = %d\n", addrlen);
  344.         print_netaddr(saddr.sa_netnum, "Callers address = ", "\n");
  345.     }
  346.     */
  347.  
  348.     *callsock = s2;
  349.  
  350.     return 0;
  351. }
  352.  
  353. /****************************************************************************
  354. *
  355. *    FUNCTION:  do_recv_send( SOCKET s2 )
  356. *
  357. *    PURPOSE:   Waits for someone to connect.
  358. *
  359. *    ARGUMENTS: SOCKET socket to transmit on
  360. *
  361. *        RETURNS:   0 if ok
  362. *                               1 if error
  363. *
  364. *\***************************************************************************/
  365. int do_recv_send(SOCKET s2)
  366. {
  367.     int rc, rcount = 0;
  368.     int nbytes, errflag = 0;
  369.     LPSTR recvbuf;
  370.  
  371.     if (verbose)
  372.         printf("allocating %d bytes for receive buffer\n", Receive_Length);
  373.  
  374.     recvbuf = malloc(Receive_Length);
  375.  
  376.     if (!recvbuf) {
  377.         printf("Error allocating %d bytes for receive buffer\n", Receive_Length);
  378.         return 1;
  379.     }
  380.  
  381.     /*
  382.     *   Recv packets and send them back
  383.     */
  384.  
  385.     while (1) {
  386.  
  387.         /*
  388.         *   Receive data
  389.         */
  390.  
  391.         if (verbose)
  392.             printf("calling recv(socket = %d, receive length = %d)\n", s2, Receive_Length);
  393.  
  394.         Sleep(Sleep_Time);
  395.  
  396.         nbytes = recv(s2, recvbuf, Receive_Length, 0);
  397.  
  398.         if (nbytes == SOCKET_ERROR) {
  399.             printf("recv call failed");
  400.             errflag++;
  401.             break;
  402.         }
  403.  
  404.         if (verbose)
  405.             printf("Received packet %d: received %d bytes\n", rcount++, nbytes);
  406.         else
  407.             printf("\rReceived packet %d: received %d bytes... ", rcount++, nbytes);
  408.  
  409.         /*
  410.         *   Send the data back
  411.         */
  412. /*
  413.         if (verbose)
  414.             printf("calling send(socket = %d, send length = %d)\n", s2, nbytes);
  415.  
  416.         rc = send(s2, recvbuf, nbytes, 0);
  417.  
  418.         if (rc == SOCKET_ERROR) {
  419.             printf("send call failed\n");
  420.             errflag++;
  421.             break;
  422.         }
  423.  
  424.         printf("Sent %d bytes", rc);
  425. */
  426.         if (verbose)
  427.             printf("\n");
  428.  
  429.         if (No_Loop)
  430.             break;
  431.     }
  432.  
  433.     if (verbose)
  434.         printf("freeing receive buffer\n");
  435.  
  436.     free(recvbuf);
  437.  
  438.     return errflag;
  439. }
  440.