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

Windows编程

开发平台:

Visual C++

  1. /****************************************************************************
  2. *  listen.c -- sample program demonstrating NWLink.
  3. *
  4. *       Microsoft Developer Support
  5. *       Copyright (c) 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. #include <windows.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <malloc.h>
  15. #include <wsipx.h>
  16. #include "../../testlib/testlib.h"
  17. /*
  18. *   Sockaddr structures 
  19. */
  20. SOCKADDR_IPX addr;
  21. SOCKADDR_IPX baddr;
  22. SOCKADDR_IPX saddr;
  23. /*
  24. *   Function Prototypes 
  25. */
  26. extern int main(int, char **);
  27. extern int net_init(SOCKET *);
  28. extern int do_listen(SOCKET);
  29. extern int wait_for_connection(SOCKET, SOCKET *);
  30. extern int do_recv_send(SOCKET);
  31. /****************************************************************************
  32. *
  33. *    FUNCTION:  main( int argc, char **argv )
  34. *
  35. *    PURPOSE:   This is the main entry for the program
  36. *        
  37. *
  38. *    ARGUMENTS: argc = Number of arguments
  39. *               argv = Array of ptrs to cmd line args
  40. *                
  41. *
  42. *  RETURNS:   Exit code for the program
  43. *
  44. ****************************************************************************/
  45. int main(int argc, char **argv)
  46. {
  47.     SOCKET s, s2;
  48.     /*
  49.     *   Set any default values before calling parse_cmd_line 
  50.     */
  51.     *Local_Socket_Number = 0x05;
  52.     *(Local_Socket_Number + 1) = 0x00;
  53.     Socket_Type = SOCK_STREAM;
  54.     Protocol = NSPROTO_SPX;
  55.     /*
  56.     *   Get any options from the command line 
  57.     */
  58.     parse_cmd_line(argc, argv);
  59.     /*
  60.     *   Initialize the network and set up our socket 
  61.     */
  62.     if (net_init(&s))
  63.         return 1;
  64.     /*
  65.     *   Go listen for a call 
  66.     */
  67.     if (do_listen(s))
  68.         return 1;
  69.     /*
  70.     *   Then wait for a connection 
  71.     */
  72.     if (wait_for_connection(s, &s2))
  73.         return 1;
  74.     /*
  75.     *   Receive data then send it back 
  76.     */
  77.     if (do_recv_send(s2))
  78.         return 1;
  79.     /*
  80.     *   All done 
  81.     */
  82.     if (verbose)
  83.         printf("closing both socketsn");
  84.     closesocket(s2);
  85.     closesocket(s);
  86.     return 0;
  87. }
  88. /****************************************************************************
  89. *
  90. *    FUNCTION:  net_init( SOCKET *skt )
  91. *
  92. *    PURPOSE:   Initializes the WinSock stuff and sets up our socket.
  93. *        
  94. *
  95. *    ARGUMENTS: SOCKET * => struct to receive our socket info
  96. *
  97. *  RETURNS:   0 if ok
  98. * 1 if error
  99. *
  100. ****************************************************************************/
  101. int net_init(SOCKET *skt)
  102. {
  103.     int rc, addrlen = 16;
  104.     int non_block = 1;
  105.     WSADATA wsdata;
  106.     SOCKET s;
  107.     WORD    wVersionRequested;
  108.     wVersionRequested = MAKEWORD(1,1);
  109.     /*
  110.     *   Initialize with the WINSOCK library 
  111.     */
  112.     if (verbose)
  113.         printf("calling WSAStartup(), ");
  114.     rc = WSAStartup(wVersionRequested, &wsdata);
  115.     if (verbose)
  116.         printf("return = 0x%X, (%d)n", rc, rc);
  117.     if (rc) {
  118.         printf("WSAStartup failed: error code = %dn", rc);
  119.         return 1;
  120.     }
  121.     if (verbose) {
  122.         printf("contents of wsdata struct: n");
  123.         print_wsa(&wsdata);
  124.     }
  125.     /*
  126.     *   Open a STREAM socket with SPX 
  127.     */
  128.     if (verbose)
  129.         printf("calling socket(addresss family = %d, socket type = %d, protocol = %d)n", Local_Address_Family, Socket_Type, Protocol);
  130.     s = socket(Local_Address_Family, Socket_Type, Protocol);
  131.     if (verbose)
  132.         printf("socket() returned 0x%X (%d)n", s, s);
  133.     if (s == INVALID_SOCKET) {
  134.         dos_net_perror("Socket call failed");
  135.         exit(1);
  136.     }
  137.     /*
  138.     *   Set the socket as non-blocking 
  139.     */
  140.     if (verbose)
  141.         printf("Calling ioctlsocket(socket = %d, cmd = FIONBIO argp = %d), ", s, non_block);
  142.     rc = ioctlsocket(s, FIONBIO, &non_block);
  143.     if (verbose)
  144.         printf("return = 0x%X (%d)n", rc, rc);
  145.     if (rc == SOCKET_ERROR) {
  146.         dos_net_perror("ioctlsocket() call failed");
  147.         closesocket(s);
  148.         exit(1);
  149.     }
  150.     /*
  151.     *   Bind to a socket.  We want to bind to a well known
  152.     *   socket so that who ever calls us will be able to.
  153.     */
  154.     addr.sa_family = Local_Address_Family;
  155.     memcpy(&addr.sa_netnum, Local_Network_Number, 4);
  156.     memcpy(&addr.sa_nodenum, Local_Node_Number, 6);
  157.     memcpy(&addr.sa_socket, Local_Socket_Number, 2);
  158.     if (verbose) {
  159.         printf("calling bind(socket = %d): n  ", s);
  160.         print_saddr(&addr);
  161.     }
  162.     rc = bind(s, (const struct sockaddr *) &addr, 16);
  163.     if (verbose)
  164.         printf("bind() returned 0x%X (%d)n", rc, rc);
  165.     if (rc == SOCKET_ERROR) {
  166.         dos_net_perror("Error binding to socket");
  167.         closesocket(s);
  168.         return 1;
  169.     }
  170.     if (verbose)
  171.         printf("calling getsockname(socket = %d), ", s);
  172.     /*
  173.     *   Get the address we bound to and print it out 
  174.     */
  175.     addrlen = 16;
  176.     rc = getsockname(s, (struct sockaddr *) &baddr, &addrlen);
  177.     if (verbose)
  178.         printf("return = 0x%X (%d)n", rc, rc);
  179.     if (rc == SOCKET_ERROR) {
  180.         dos_net_perror("Error getting socket name");
  181.         closesocket(s);
  182.         return 1;
  183.     }
  184.     /*
  185.     *   Print out the network address 
  186.     */
  187.     if (verbose) {
  188.         printf("addrlen = %dn", addrlen);
  189.         print_netaddr(baddr.sa_netnum, "Bound address = ", "n");
  190.     }
  191.     *skt = s;
  192.     return 0;
  193. }
  194. /****************************************************************************
  195. *
  196. *    FUNCTION:  do_listen( SOCKET s )
  197. *
  198. *    PURPOSE:   Sets the socket up for listening.
  199. *
  200. *    ARGUMENTS: SOCKET socket to listen on
  201. *
  202. *  RETURNS:   0 if ok
  203. * 1 if error
  204. *
  205. ****************************************************************************/
  206. int do_listen(SOCKET s)
  207. {
  208.     int rc;
  209.     /*
  210.     *   Enable this socket as a listen socket that can
  211.     *   take <Backlog> connection indication(s) at a time.
  212.     */
  213.     if (verbose)
  214.         printf("calling listen(socket = %d, backlog = %d), ", s, Backlog);
  215.     rc = listen(s, Backlog);
  216.     if (verbose)
  217.         printf("return = 0x%X (%d)n", rc, rc);
  218.     if (rc == SOCKET_ERROR) {
  219.         dos_net_perror("listen call failed");
  220.         closesocket(s);
  221.         return 1;
  222.     }
  223.     /*
  224.     *   Wait for a connection and get the connecting socket 
  225.     */
  226.     return 0;
  227. }
  228. /****************************************************************************
  229. *
  230. *    FUNCTION:  wait_for_connection( SOCKET s, SOCKET *callsock )
  231. *
  232. *    PURPOSE:   Waits for someone to connect.
  233. *
  234. *    ARGUMENTS: SOCKET socket we are listening on
  235. * SOCKET * => area to store client socket info after
  236. *             connect
  237. *
  238. *  RETURNS:   0 if ok
  239. * 1 if error
  240. *
  241. ****************************************************************************/
  242. int wait_for_connection(SOCKET s, SOCKET *callsock)
  243. {
  244.     SOCKET s2;
  245.     int addrlen = 16;
  246.     /*
  247.     *   Poll the accept() call until it returns
  248.     *   something other than WSAEWOULDBLOCK
  249.     *   We will print out little '.' while we wait.
  250.     */
  251.     if (verbose)
  252.         printf("Polling socket every 1/2 second");
  253.     else
  254.         printf("Waiting for call");
  255.     do {
  256.         s2 = accept(s, (struct sockaddr *) &saddr, &addrlen);
  257.         /*
  258.         *   Wait 1/2 second and try again 
  259.         */
  260.         Sleep(500);
  261.         printf(".");
  262.     }
  263.     while (s2 == INVALID_SOCKET && h_errno == WSAEWOULDBLOCK);
  264.     printf("n");
  265.     if (verbose)
  266.         printf("naccept() returned, new socket = 0x%X (%d)n", s2, s2);
  267.     if (s2 == INVALID_SOCKET) {
  268.         dos_net_perror("accept call failed");
  269.         closesocket(s);
  270.         return 1;
  271.     }
  272.     /*
  273.     *   Print out who connected to us 
  274.     */
  275.     if (verbose) {
  276.         printf("addrlen = %dn", addrlen);
  277.         print_netaddr(saddr.sa_netnum, "Callers address = ", "n");
  278.     }
  279.     *callsock = s2;
  280.     return 0;
  281. }
  282. /****************************************************************************
  283. *
  284. *    FUNCTION:  do_recv_send( SOCKET s2 )
  285. *
  286. *    PURPOSE:   Waits for someone to connect.
  287. *
  288. *    ARGUMENTS: SOCKET socket to transmit on
  289. *
  290. *  RETURNS:   0 if ok
  291. * 1 if error
  292. *
  293. ****************************************************************************/
  294. int do_recv_send(SOCKET s2)
  295. {
  296.     int rc, rcount = 0;
  297.     int nbytes, errflag = 0;
  298.     LPSTR recvbuf;
  299.     if (verbose)
  300.         printf("allocating %d bytes for receive buffern", Receive_Length);
  301.     recvbuf = malloc(Receive_Length);
  302.     if (!recvbuf) {
  303.         printf("Error allocating %d bytes for receive buffern", Receive_Length);
  304.         return 1;
  305.     }
  306.     /*
  307.     *   Recv packets and send them back 
  308.     */
  309.     while (1) {
  310.         /*
  311.         *   Receive data 
  312.         */
  313.         if (verbose)
  314.             printf("calling recv(socket = %d, receive length = %d)n", s2, Receive_Length);
  315.         nbytes = recv(s2, recvbuf, Receive_Length, 0);
  316.         if (nbytes == SOCKET_ERROR) {
  317.             dos_net_perror("recv call failed");
  318.             errflag++;
  319.             break;
  320.         }
  321.         if (verbose)
  322.             printf("Received packet %d: received %d bytesn", rcount++, nbytes);
  323.         else
  324.             printf("rReceived packet %d: received %d bytes... ", rcount++, nbytes);
  325.         /*
  326.         *   Send the data back 
  327.         */
  328.         if (verbose)
  329.             printf("calling send(socket = %d, send length = %d)n", s2, nbytes);
  330.         rc = send(s2, recvbuf, nbytes, 0);
  331.         if (rc == SOCKET_ERROR) {
  332.             dos_net_perror("send call failed");
  333.             errflag++;
  334.             break;
  335.         }
  336.         printf("Sent %d bytes", rc);
  337.         if (verbose)
  338.             printf("n");
  339.         if (No_Loop)
  340.             break;
  341.     }
  342.     if (verbose)
  343.         printf("freeing receive buffern");
  344.     free(recvbuf);
  345.     return errflag;
  346. }