Annotation of mstools/samples/wsock/wsock.c, revision 1.1.1.1

1.1       root        1: 
                      2: //-----------------------------------------------------------------------------
                      3: // This is a part of the Microsoft Source Code Samples. 
                      4: // Copyright (C) 1993 Microsoft Corporation.
                      5: // All rights reserved. 
                      6: //  
                      7: // This source code is only intended as a supplement to 
                      8: // Microsoft Development Tools and/or WinHelp documentation.
                      9: // See these sources for detailed information regarding the 
                     10: // Microsoft samples programs.
                     11: //-----------------------------------------------------------------------------
                     12: 
                     13: /****************************************************************************\
                     14: *  wsock.c -- sample program demonstrating Windows Sockets APIs.
                     15: *
                     16: *  Demonstrates basic sockets programming with the Windows Sockets API.
                     17: *  Allows two occurances of the application to connect.  Also, displays
                     18: *  information about a host computer.
                     19: *
                     20: ****************************************************************************/
                     21: 
                     22: #include <windows.h>       /* required for all Windows applications */
                     23: #include <winsock.h>
                     24: #include <stdio.h>         /* for sprintf                           */
                     25: #include <string.h>        /* for strlen                            */
                     26: #include <memory.h>
                     27: #include <process.h>       /* for _beginthread                      */
                     28: #include "wsock.h"         /* specific to this program              */
                     29: 
                     30: HANDLE hInst;              /* current instance                      */
                     31: 
                     32: SOCKET sock;
                     33: u_short portno;            /* Which tcp port are we going to use?   */
                     34: 
                     35: char szBuff[ 80 ];         /* Temp buffer - used to pass strings    */
                     36:                            /* to and from dialog boxes, etc         */
                     37: 
                     38: #define MAX_PENDING_CONNECTS 4  /* The backlog allowed for listen() */
                     39: #define NO_FLAGS_SET         0  /* Used with recv()/send()          */
                     40: #define MY_MSG_LENGTH       80  /* msg buffer sent back and forth   */
                     41: 
                     42: /****************************************************************************
                     43: *
                     44: *    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
                     45: *
                     46: *    PURPOSE: calls initialization function, processes message loop
                     47: *
                     48: *\***************************************************************************/
                     49: 
                     50: WINAPI WinMain(
                     51:     HANDLE hInstance,
                     52:     HANDLE hPrevInstance,
                     53:     LPSTR lpCmdLine,
                     54:     int nCmdShow
                     55:     )
                     56: {
                     57: 
                     58:     MSG msg;
                     59: 
                     60:     UNREFERENCED_PARAMETER( lpCmdLine );
                     61: 
                     62:     if (!hPrevInstance)                  /* Other instances of app running? */
                     63:         if (!InitApplication(hInstance)) /* Initialize shared things        */
                     64:             return (FALSE);              /* Exits if unable to initialize   */
                     65: 
                     66:     /*
                     67:     *   Perform initializations that apply to a specific instance
                     68:     */
                     69:     if (!InitInstance(hInstance, nCmdShow))
                     70:         return (FALSE);
                     71: 
                     72:     /*
                     73:     *   Acquire and dispatch messages until a WM_QUIT message is received.
                     74:     */
                     75:     while (GetMessage(&msg,        /* message structure                      */
                     76:             NULL,                  /* handle of window receiving the message */
                     77:             0,             /* lowest message to examine              */
                     78:             0))            /* highest message to examine             */
                     79:         {
                     80:         TranslateMessage(&msg);    /* Translates virtual key codes           */
                     81:         DispatchMessage(&msg);     /* Dispatches message to window           */
                     82:    }
                     83:     return (msg.wParam);           /* Returns the value from PostQuitMessage */
                     84: }
                     85: 
                     86: 
                     87: /****************************************************************************
                     88: *
                     89: *    FUNCTION: InitApplication(HANDLE)
                     90: *
                     91: *    PURPOSE: Initializes window data and registers window class
                     92: *
                     93: *\***************************************************************************/
                     94: 
                     95: BOOL InitApplication(HANDLE hInstance)       /* current instance             */
                     96: {
                     97:     WNDCLASS  wc;
                     98: 
                     99:     /* Fill in window class structure with parameters that describe the       */
                    100:     /* main window.                                                           */
                    101: 
                    102:     wc.style = 0;                    /* Class style(s).                    */
                    103:     wc.lpfnWndProc = (WNDPROC)MainWndProc;       /* Function to retrieve messages for  */
                    104:                                         /* windows of this class.             */
                    105:     wc.cbClsExtra = 0;                  /* No per-class extra data.           */
                    106:     wc.cbWndExtra = 0;                  /* No per-window extra data.          */
                    107:     wc.hIcon = LoadIcon (hInstance, "wsockicon"); /* Icon name from .RC        */
                    108:     wc.hInstance = hInstance;          /* Application that owns the class.   */
                    109:     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
                    110:     wc.hbrBackground = GetStockObject(WHITE_BRUSH);
                    111:     wc.lpszMenuName =  "WSockMenu";   /* Name of menu resource in .RC file. */
                    112:     wc.lpszClassName = "WSockWClass"; /* Name used in call to CreateWindow. */
                    113: 
                    114:     /* Register the window class and return success/failure code. */
                    115: 
                    116:     return (RegisterClass(&wc));
                    117: 
                    118: }
                    119: 
                    120: 
                    121: /****************************************************************************\
                    122: *
                    123: *    FUNCTION:  InitInstance(HANDLE, int)
                    124: *
                    125: *    PURPOSE:  Saves instance handle and creates main window
                    126: *
                    127: *\***************************************************************************/
                    128: 
                    129: BOOL InitInstance(
                    130:     HANDLE          hInstance,          /* Current instance identifier.       */
                    131:     int             nCmdShow)           /* Param for first ShowWindow() call. */
                    132: {
                    133:     HWND            hWnd;               /* Main window handle.                */
                    134: 
                    135:     /* Save the instance handle in static variable, which will be used in  */
                    136:     /* many subsequence calls from this application to Windows.            */
                    137: 
                    138:     hInst = hInstance;
                    139: 
                    140:     /* Create a main window for this application instance.  */
                    141: 
                    142:     hWnd = CreateWindow(
                    143:         "WSockWClass",                  /* See RegisterClass() call.          */
                    144:         "Windows Sockets Sample Application",   /* Text for window title bar.         */
                    145:         WS_OVERLAPPEDWINDOW,            /* Window style.                      */
                    146:         CW_USEDEFAULT,                  /* Default horizontal position.       */
                    147:         CW_USEDEFAULT,                  /* Default vertical position.         */
                    148:         CW_USEDEFAULT,                  /* Default width.                     */
                    149:         CW_USEDEFAULT,                  /* Default height.                    */
                    150:         NULL,                           /* Overlapped windows have no parent. */
                    151:         NULL,                           /* Use the window class menu.         */
                    152:         hInstance,                      /* This instance owns this window.    */
                    153:         NULL                            /* Pointer not needed.                */
                    154:     );
                    155: 
                    156:     /* If window could not be created, return "failure" */
                    157: 
                    158:     if (!hWnd)
                    159:         return (FALSE);
                    160: 
                    161:     /* Make the window visible; update its client area; and return "success" */
                    162: 
                    163:     ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
                    164:     UpdateWindow(hWnd);          /* Sends WM_PAINT message                 */
                    165:     return (TRUE);               /* Returns the value from PostQuitMessage */
                    166: 
                    167: }
                    168: 
                    169: /****************************************************************************\
                    170: *
                    171: *    FUNCTION: AcceptThreadProc(PTHREADPACK tp)
                    172: *
                    173: *    PURPOSE:  Use blocking accept() calls and display a message box when
                    174: *              a connection is made.
                    175: *
                    176: *\***************************************************************************/
                    177: 
                    178: void AcceptThreadProc( PTHREADPACK ptp )
                    179: {
                    180:    SOCKADDR_IN acc_sin;    /* Accept socket address - internet style */
                    181:    int acc_sin_len;        /* Accept socket address length */
                    182:    int status;
                    183:    char szMsg[ MY_MSG_LENGTH ];
                    184: 
                    185: 
                    186:    acc_sin_len = sizeof(acc_sin);
                    187: 
                    188:    wsprintf( szBuff, "thread #%d created.", ptp->nThread);
                    189:    MessageBox(ptp->hWnd, szBuff, "FYI", MB_OK);
                    190: 
                    191:    sock = accept( sock,(struct sockaddr FAR *) &acc_sin,
                    192:             (int FAR *) &acc_sin_len );
                    193: 
                    194:    if (sock < 0) {
                    195:       sprintf(szBuff, "%d is the error", WSAGetLastError());
                    196: 
                    197:       MessageBox(ptp->hWnd, szBuff, "accept(sock) failed", MB_OK);
                    198: 
                    199:    }
                    200: 
                    201:    wsprintf( szBuff, "Thread #%d accepted something\n\nCheck for incoming messages?", ptp->nThread);
                    202: 
                    203:    /*
                    204:    *   Now have a connection --
                    205:    *   SetConnectMenus() grays/enables proper menu items
                    206:    */
                    207:    SetConnectMenus( ptp->hWnd );
                    208: 
                    209: 
                    210:    while (1) {
                    211: 
                    212:       /*
                    213:       *   By default sockets are created in blocking mode.
                    214:       *   Just keep reading until process destroyed.
                    215:       */
                    216:       status = recv( sock, szMsg, MY_MSG_LENGTH, NO_FLAGS_SET );
                    217: 
                    218:       if (status == SOCKET_ERROR) {
                    219:          wsprintf( szMsg, "Error %d", WSAGetLastError() );
                    220:          MessageBox( ptp->hWnd, szMsg, "Error with recv()", MB_OK);
                    221:          _endthread();
                    222:       }
                    223:           szMsg[status] = '\0';  /* NULL-terminate the string */
                    224: 
                    225:       if (status)
                    226:          MessageBox( ptp->hWnd, szMsg, "From thread", MB_OK);
                    227:       else  {
                    228:          MessageBox( ptp->hWnd, "Connection broken", "Error", MB_OK);
                    229:          _endthread();
                    230:       }
                    231: 
                    232:    }    /* while (forever) */
                    233: }
                    234: 
                    235: /****************************************************************************\
                    236: *
                    237: *    FUNCTION:  FillAddr(HWND, PSOCKADDR_IN, BOOL)
                    238: *
                    239: *    PURPOSE:  Retrieves the IP address and port number.
                    240: *
                    241: *    COMMENTS:
                    242: *        This function is called in two conditions.
                    243: *            1.) When a client is preparing to call connect(), or
                    244: *            2.) When a server host is going to call bind(), listen() and
                    245: *                accept().
                    246: *        In both situations, a SOCKADDR_IN structure is filled.
                    247: *        However, different fields are filled depending on the condition.
                    248: *
                    249: *   ASSUMPTION:
                    250: *      szBuff is a global variable that contains the remote host name or NULL
                    251: *      if local.
                    252: *      bConnect determines if the socket address is being set up for a listen()
                    253: *      (bConnect == TRUE) or a connect() (bConnect == FALSE)
                    254: *
                    255: *
                    256: *\***************************************************************************/
                    257: 
                    258: BOOL FillAddr(
                    259:         HWND hWnd,
                    260:         PSOCKADDR_IN psin,
                    261:         BOOL bConnect)
                    262: {
                    263:    DWORD dwSize;
                    264:    PHOSTENT phe;
                    265:    PSERVENT pse;
                    266:    char szTemp[200];
                    267:    int status;
                    268: 
                    269: 
                    270:    psin->sin_family = AF_INET;
                    271: 
                    272: 
                    273:    /*
                    274:    *   If we are setting up for a listen() call (bConnect = FALSE),
                    275:    *   fill servent with our address.
                    276:    */
                    277:    if (!bConnect) {
                    278: 
                    279:       /*
                    280:       *   Retrieve my ip address.  Assuming the hosts file in
                    281:       *   in %systemroot%/system/drivers/etc/hosts contains my computer name.
                    282:       */
                    283: 
                    284:       dwSize = sizeof(szBuff);
                    285:       gethostname(szBuff, dwSize);
                    286:         }
                    287: 
                    288: 
                    289:    phe = gethostbyname(szBuff);
                    290:    if (phe == NULL) {
                    291:       sprintf(szTemp, "%d is the error. Make sure '%s' is listed in the hosts file.", WSAGetLastError(), szBuff);
                    292: 
                    293:       MessageBox(hWnd, szTemp, "gethostbyname() failed.", MB_OK);
                    294:       return FALSE;
                    295:    }
                    296:    memcpy((char FAR *)&(psin->sin_addr), phe->h_addr,
                    297:       phe->h_length);
                    298: 
                    299: 
                    300:    /*
                    301:    *   Retrieve the Port number
                    302:    */
                    303:    status = DialogBox(hInst,             /* current instance         */
                    304:       "TCPPORTNUM",                      /* resource to use          */
                    305:       hWnd,                              /* parent handle            */
                    306:       GetTcpPort);                       /* instance address         */
                    307: 
                    308:    switch(status) {
                    309:       case 0:               /* User cancelled request from prev. dialog box */
                    310:          return FALSE;
                    311: 
                    312:       case 1:               /* actual port number entered */
                    313:          psin->sin_port = htons(portno);        /* Convert to network ordering */
                    314:          break;
                    315: 
                    316:       case 2:               /* service name entereted */
                    317:          /*
                    318:          *   Find the service name, szBuff, which is a type tcp protocol in
                    319:          *   the "services" file.
                    320:          */
                    321:          pse = getservbyname(szBuff, "tcp");
                    322:          if (pse == NULL)  {
                    323:             sprintf(szBuff, "%d is the error. Make sure this is a valid TCP service.", WSAGetLastError());
                    324:             MessageBox(hWnd, szBuff, "getservbyname(sock) failed", MB_OK);
                    325:             return FALSE;
                    326:          }
                    327:          psin->sin_port = pse->s_port;
                    328:          break;
                    329: 
                    330:       default:
                    331:          return FALSE;
                    332:    }
                    333:    return TRUE;
                    334: }
                    335: 
                    336: /****************************************************************************
                    337: *
                    338: *    FUNCTION: SetConnectMenus( HWND )
                    339: *
                    340: *    PURPOSE: Gray/Enable the proper menu items after a connection has been
                    341: *             established.
                    342: *
                    343: *\***************************************************************************/
                    344: 
                    345: void SetConnectMenus( HWND hWnd )
                    346: {
                    347:    /*
                    348:    *   Disable/enable proper menu items.
                    349:    */
                    350:    EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_ENABLED );
                    351:    EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_GRAYED );
                    352:    EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_GRAYED );
                    353:    EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_GRAYED );
                    354:    EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_GRAYED );
                    355:    EnableMenuItem(GetMenu( hWnd ), IDM_CANCEL, MF_GRAYED );
                    356:    EnableMenuItem(GetMenu( hWnd ), IDM_SENDTCP, MF_ENABLED );
                    357: 
                    358:    /*
                    359:    *   Reflect socket connection in title bar.
                    360:    */
                    361:    SetWindowText( hWnd, "Connected");
                    362: }
                    363: 
                    364: /****************************************************************************\
                    365: *
                    366: *    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
                    367: *
                    368: *    PURPOSE:  Processes main window messages
                    369: *
                    370: * MESSAGES:
                    371: *  WM_CREATE   - call WSAStartUp() and display description message
                    372: *  WSA_ACCEPT  - User-defined message used with WSAAsyncSelect().  Sent
                    373: *                by the Windows Sockets DLL when a socket connection is
                    374: *                pending.
                    375: *
                    376: *  WM_COMMAND
                    377: *  IDM_CONNECT - Connect to a remote host.
                    378: *  IDM_LISTEN  - Use the BSD-Style accept().
                    379: *  IDM_ALISTEN - Use the Windows Sockets Asynchronous APIs to detect when
                    380: *                a connection is made.
                    381: *  IDM_CANCEL  - Cancel the Asynchronous call above.
                    382: *  IDM_TLISTEN - Uses two threads to accept network connections (using the
                    383: *                BSD-Style accept().
                    384: *  IDM_HOSTNAME- Display information about a host.
                    385: *  IDM_ABOUT   - About box.
                    386: *
                    387: *  WM_DESTROY  - destroy window and call the WSACleanUp()
                    388: *
                    389: *\***************************************************************************/
                    390: 
                    391: LONG APIENTRY MainWndProc(
                    392:         HWND hWnd,                /* window handle                   */
                    393:         UINT message,             /* type of message                 */
                    394:         UINT wParam,              /* additional information          */
                    395:         LONG lParam)              /* additional information          */
                    396: {
                    397:    int status;             /* Status Code */
                    398:    SOCKADDR_IN local_sin;  /* Local socket - internet style */
                    399:    SOCKADDR_IN acc_sin;    /* Accept socket address - internet style */
                    400:    int acc_sin_len;        /* Accept socket address length */
                    401: 
                    402: 
                    403:    switch (message) {
                    404:    case WM_CREATE:
                    405:    {
                    406:       WSADATA WSAData;
                    407:       char szTemp[80];
                    408: 
                    409:       if ((status = WSAStartup(MAKEWORD(1,1), &WSAData)) == 0) {
                    410:          MessageBox( hWnd, WSAData.szDescription, WSAData.szSystemStatus, MB_OK);
                    411:       }
                    412:       else {
                    413:          sprintf(szTemp, "%d is the err", status);
                    414:          MessageBox( hWnd, szTemp, "Error", MB_OK);
                    415:       }
                    416:    }
                    417:    break;   /* WM_CREATE */
                    418: 
                    419:    /*
                    420:    *    Notification if data is waiting on a socket.  This comes
                    421:    *    from Windows Sockets (via WSAAsyncSelect()).
                    422:    */
                    423:    case WSA_READ:
                    424:    {
                    425:       char szTemp[ MY_MSG_LENGTH ];
                    426: 
                    427:       if (WSAGETSELECTEVENT(lParam) == FD_READ) {
                    428:          status = recv((SOCKET)wParam, szTemp, MY_MSG_LENGTH, NO_FLAGS_SET );
                    429: 
                    430:          if (status) {
                    431:             szTemp[ status ] = '\0';
                    432:             MessageBox( hWnd, szTemp, "WSA_READ", MB_OK);
                    433:          }
                    434:          else
                    435:             MessageBox( hWnd, "Connection broken", "Error", MB_OK);
                    436:       }
                    437:       else {    /* FD_CLOSE -- connection dropped */
                    438:          MessageBox( hWnd, "Connection lost", "WSA_READ", MB_OK);
                    439:          EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_ENABLED);
                    440:          EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_ENABLED);
                    441:          EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_ENABLED);
                    442:          EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_ENABLED);
                    443:          EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_ENABLED);
                    444:          EnableMenuItem(GetMenu( hWnd ), IDM_CANCEL, MF_GRAYED);
                    445:          EnableMenuItem(GetMenu( hWnd ), IDM_SENDTCP, MF_GRAYED);
                    446:       }
                    447: 
                    448: 
                    449:    }
                    450:    break;       /* WSA_READ*/
                    451: 
                    452:    case WSA_ACCEPT: /* Notification if a socket connection is pending. */
                    453:       /*
                    454:       *   Disable/enable proper menu items.
                    455:       */
                    456:       EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_ENABLED);
                    457:       EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_ENABLED);
                    458:       EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_ENABLED);
                    459:       EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_ENABLED);
                    460:       EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_ENABLED);
                    461:       EnableMenuItem(GetMenu( hWnd ), IDM_CANCEL, MF_GRAYED);
                    462: 
                    463:       if (WSAGETSELECTERROR( lParam ) == 0) {   /* Success */
                    464: 
                    465:          /*
                    466:          *   Accept the incoming connection.
                    467:          */
                    468:          acc_sin_len = sizeof( acc_sin );
                    469:          sock = accept( sock,(struct sockaddr FAR *) &acc_sin,
                    470:             (int FAR *) &acc_sin_len );
                    471: 
                    472:          if (sock < 0) {
                    473:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    474: 
                    475:             MessageBox(hWnd, szBuff, "accept(sock) failed", MB_OK);
                    476:             break;
                    477:          }
                    478: 
                    479:          MessageBox(hWnd, "accept()", "Accepted a connection!", MB_OK);
                    480: 
                    481:          /*
                    482:          *   Now have a connection --
                    483:          *   SetConnectMenus() grays/enables proper menu items
                    484:          */
                    485:          SetConnectMenus( hWnd );
                    486: 
                    487:          /*
                    488:          *   Send main window a WSA_READ when either data is pending on
                    489:          *   the socket (FD_READ) or the connection is closed (FD_CLOSE)
                    490:          */
                    491:          if ((status = WSAAsyncSelect( sock, hWnd, WSA_READ, FD_READ | FD_CLOSE )) > 0) {
                    492:             wsprintf(szBuff, "%d (0x%x)", status, status);
                    493:             MessageBox( hWnd, "Error on WSAAsyncSelect()", szBuff, MB_OK);
                    494:             closesocket( sock );
                    495:          }
                    496:       }
                    497:       else {
                    498:          MessageBox(hWnd, "accept()", "Error occured!", MB_OK);
                    499: 
                    500:          /*
                    501:          *   Cancel any further notifications.
                    502:          */
                    503:          WSAAsyncSelect( sock, hWnd, 0, 0);
                    504:          SetWindowText( hWnd, "Async Listen call canceled");
                    505:       }
                    506:       break;   /* WSA_ACCEPT */
                    507: 
                    508: 
                    509: 
                    510:    case WM_COMMAND:        /* message: command from application menu */
                    511:       switch(LOWORD(wParam)) {
                    512:       case IDM_CONNECT: /* Client - connect to remote host */
                    513:       {
                    514:          /*
                    515: 
                    516:          When a network client wants to connect to a server,
                    517:          it must have:
                    518:             1.) a TCP port number (gotten via getservbyname())
                    519:             and
                    520:             2.) an IP address of the remote host (gotten via gethostbyname()).
                    521: 
                    522:          The following summarizes the steps used to connect.
                    523:          Make a dialog box (HostName)
                    524:          Get the name of the remote host computer in which
                    525:           to connect from the user (store string in "szBuff" global var)
                    526:        * Check to see if the hosts file knows the computer (gethostbyname)
                    527:        * Get the host information (hostent structure filled)
                    528:        * Fill in the address of the remote host into the servent structure (memcpy)
                    529:        * Make a dialog box (TCPPORTNUM)
                    530:        * Get the NAME of the port to connect to on the remote host from the
                    531:          user.
                    532:        * Get the port number (getservbyname)
                    533:        * Fill in the port number of the servent structure
                    534:          Establish a connection (connect)
                    535: 
                    536:          The * prefixed steps are done in the FillAddr() procedure.
                    537: 
                    538: 
                    539:          */
                    540:          SOCKADDR_IN dest_sin;  /* DESTination Socket INternet */
                    541: 
                    542: 
                    543: 
                    544:          /* Get the name of the remote host. Store the string in szBuff. */
                    545: 
                    546:          status = DialogBox(hInst,
                    547:             "HOSTNAME",
                    548:             hWnd,
                    549:             GetHostName);
                    550: 
                    551:          if (!status)   /* User cancelled request from prev. dialog box */
                    552:             break;
                    553: 
                    554:          sock = socket( AF_INET, SOCK_STREAM, 0);
                    555:          if (sock == INVALID_SOCKET) {
                    556:             MessageBox(hWnd, "socket() failed", "Error", MB_OK);
                    557:             break;
                    558:          }
                    559: 
                    560:          /*
                    561:          *    Retrieve the IP address and TCP Port number
                    562:          *    Global variable szBuff contains the remote host name.
                    563:          */
                    564:          if (!FillAddr( hWnd, &dest_sin, TRUE)) {
                    565:             closesocket( sock );
                    566:             break;
                    567:          }
                    568: 
                    569: 
                    570:          if (connect( sock, (PSOCKADDR) &dest_sin, sizeof( dest_sin)) < 0) {
                    571:             closesocket( sock );
                    572:             MessageBox(hWnd, "connect() failed", "Error", MB_OK);
                    573:             break;
                    574:          }
                    575:          MessageBox(hWnd, "connect() worked!", "Success!", MB_OK);
                    576: 
                    577:          /*
                    578:          *   Now have a connection --
                    579:          *   SetConnectMenus() grays/enables proper menu items
                    580:          */
                    581:          SetConnectMenus( hWnd );
                    582: 
                    583:          /*
                    584:          *   Send main window a WSA_READ when either data is pending on
                    585:          *   the socket (FD_READ) or the connection is closed (FD_CLOSE)
                    586:          */
                    587:          if ((status = WSAAsyncSelect( sock, hWnd, WSA_READ, FD_READ | FD_CLOSE )) > 0) {
                    588:             wsprintf(szBuff, "%d (0x%x)");
                    589:             MessageBox( hWnd, "Error on WSAAsyncSelect()", szBuff, MB_OK);
                    590:             closesocket( sock );
                    591:          }
                    592: 
                    593:       }
                    594:       break;   /* IDM_CONNECT */
                    595: 
                    596:       case IDM_LISTEN:
                    597:       {
                    598:          sock = socket( AF_INET, SOCK_STREAM, 0);
                    599:          if (sock == INVALID_SOCKET) {
                    600:             MessageBox(hWnd, "socket() failed", "Error", MB_OK);
                    601:             closesocket(sock);
                    602:             break;
                    603:          }
                    604: 
                    605:          /*
                    606:          *   Retrieve the IP address and TCP Port number
                    607:          */
                    608: 
                    609:          if (!FillAddr(hWnd, &local_sin, FALSE ))
                    610:             break;
                    611: 
                    612:          /*
                    613:          *   Disable/enable proper menu items.
                    614:          */
                    615:          EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_GRAYED);
                    616:          EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_GRAYED);
                    617:          EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_GRAYED);
                    618:          EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_GRAYED);
                    619:          EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_GRAYED);
                    620: 
                    621:          SetWindowText( hWnd, "Waiting for connection..");
                    622: 
                    623: 
                    624:          /*
                    625:          *   Associate an address with a socket. (bind)
                    626:          */
                    627:          if (bind( sock, (struct sockaddr FAR *) &local_sin, sizeof(local_sin)) == SOCKET_ERROR) {
                    628:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    629: 
                    630:             MessageBox(hWnd, szBuff, "bind(sock) failed", MB_OK);
                    631:             break;
                    632:          }
                    633: 
                    634:          if (listen( sock, MAX_PENDING_CONNECTS ) < 0) {
                    635:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    636: 
                    637:             MessageBox(hWnd, szBuff, "listen(sock) failed", MB_OK);
                    638:             break;
                    639:          }
                    640: 
                    641:          acc_sin_len = sizeof(acc_sin);
                    642: 
                    643: 
                    644:          sock = accept( sock,(struct sockaddr FAR *) &acc_sin,
                    645:             (int FAR *) &acc_sin_len );
                    646:          if (sock < 0) {
                    647:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    648: 
                    649:             MessageBox(hWnd, szBuff, "accept(sock) failed", MB_OK);
                    650:             break;
                    651:          }
                    652: 
                    653:          MessageBox(hWnd, "accept()", "Accepted a connection!", MB_OK);
                    654: 
                    655:          /*
                    656:          *   Now have a connection --
                    657:          *   SetConnectMenus() grays/enables proper menu items
                    658:          */
                    659:          SetConnectMenus( hWnd );
                    660: 
                    661:          /*
                    662:          *   Send main window a WSA_READ when either data is pending on
                    663:          *   the socket (FD_READ) or the connection is closed (FD_CLOSE)
                    664:          */
                    665:          if ((status = WSAAsyncSelect( sock, hWnd, WSA_READ, FD_READ | FD_CLOSE )) > 0) {
                    666:             wsprintf(szBuff, "%d (0x%x)");
                    667:             MessageBox( hWnd, "Error on WSAAsyncSelect()", szBuff, MB_OK);
                    668:             closesocket( sock );
                    669:          }
                    670: 
                    671:       }
                    672:       break;   /* IDM_LISTEN */
                    673: 
                    674:       /*
                    675:       *   Asynchronous Listen - Using WSA extensions.
                    676:       */
                    677:       case IDM_ALISTEN:
                    678:       {
                    679: 
                    680:          sock = socket( AF_INET, SOCK_STREAM, 0);
                    681:          if (sock == INVALID_SOCKET) {
                    682:             MessageBox(hWnd, "socket() failed", "Error", MB_OK);
                    683:             break;
                    684:          }
                    685:          /*
                    686:          *   Retrieve the IP address and TCP Port number
                    687:          */
                    688: 
                    689:          if (!FillAddr( hWnd, &local_sin, FALSE)) {
                    690:             closesocket( sock );
                    691:             break;
                    692:          }
                    693: 
                    694:          /*
                    695:          *   Disable/enable proper menu items.
                    696:          */
                    697:          EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_GRAYED);
                    698:          EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_GRAYED);
                    699:          EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_GRAYED);
                    700:          EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_GRAYED);
                    701:          EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_GRAYED);
                    702:          EnableMenuItem(GetMenu( hWnd ), IDM_CANCEL, MF_ENABLED);
                    703: 
                    704:          SetWindowText( hWnd, "Waiting for connection.. (Async)");
                    705: 
                    706: 
                    707:          /*
                    708:          *   Associate an address with a socket. (bind)
                    709:          */
                    710:          if (bind( sock, (struct sockaddr FAR *) &local_sin, sizeof(local_sin)) == SOCKET_ERROR) {
                    711:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    712: 
                    713:             MessageBox(hWnd, szBuff, "bind(sock) failed", MB_OK);
                    714:             closesocket( sock );
                    715:             break;
                    716:          }
                    717: 
                    718:          if (listen( sock, MAX_PENDING_CONNECTS ) < 0) {
                    719:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    720: 
                    721:             MessageBox(hWnd, szBuff, "listen(sock) failed", MB_OK);
                    722:             break;
                    723:          }
                    724: 
                    725:          /*
                    726:          *   Send window a WSA_ACCEPT when something is trying to connect.
                    727:          */
                    728:          if ((status = WSAAsyncSelect( sock, hWnd, WSA_ACCEPT, FD_ACCEPT)) > 0) {
                    729:             wsprintf( szBuff, "%d (0x%x)");
                    730:             MessageBox( hWnd, "Error on WSAAsyncSelect()", szBuff, MB_OK);
                    731:             SetWindowText( hWnd, "Async listen cancelled");
                    732:             closesocket( sock );
                    733:          }
                    734: 
                    735:       }
                    736:       break;   /* IDM_ALISTEN */
                    737: 
                    738: 
                    739:       /*
                    740:       *   Cancel an asynchronous call.
                    741:       */
                    742:       case IDM_CANCEL:
                    743:          WSAAsyncSelect( sock, hWnd, 0, 0);
                    744:          SetWindowText( hWnd, "Async Listen cancelled..");
                    745: 
                    746:          /*
                    747:          *   Disable/enable proper menu items.
                    748:          */
                    749:          EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_ENABLED);
                    750:          EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_ENABLED);
                    751:          EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_ENABLED);
                    752:          EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_ENABLED);
                    753:          EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_ENABLED);
                    754:          EnableMenuItem(GetMenu( hWnd ), IDM_CANCEL, MF_GRAYED);
                    755:          EnableMenuItem(GetMenu( hWnd ), IDM_SENDTCP, MF_GRAYED);
                    756: 
                    757:          break;   /* IDM_CANCEL */
                    758: 
                    759:       /*
                    760:       * Listen in the main thread -- spawn and accept two network
                    761:       *  connections inside two threads.
                    762:       */
                    763:       case IDM_TLISTEN:
                    764:       {
                    765:          static THREADPACK tp;
                    766: 
                    767:          sock = socket( AF_INET, SOCK_STREAM, 0);
                    768:          if (sock == INVALID_SOCKET) {
                    769:             MessageBox(hWnd, "socket() failed", "Error", MB_OK);
                    770:             closesocket(sock);
                    771:             break;
                    772:          }
                    773: 
                    774:          /*
                    775:          *   Retrieve the IP address and TCP Port number
                    776:          */
                    777: 
                    778:          if (!FillAddr(hWnd, &local_sin, FALSE ))
                    779:             break;
                    780: 
                    781:          /*
                    782:          *   Disable/enable proper menu items.
                    783:          */
                    784:          EnableMenuItem(GetMenu( hWnd ), IDM_HOSTNAME, MF_GRAYED);
                    785:          EnableMenuItem(GetMenu( hWnd ), IDM_LISTEN, MF_GRAYED);
                    786:          EnableMenuItem(GetMenu( hWnd ), IDM_ALISTEN, MF_GRAYED);
                    787:          EnableMenuItem(GetMenu( hWnd ), IDM_TLISTEN, MF_GRAYED);
                    788:          EnableMenuItem(GetMenu( hWnd ), IDM_CONNECT, MF_GRAYED);
                    789:          EnableMenuItem(GetMenu( hWnd ), IDM_SENDTCP, MF_GRAYED);
                    790: 
                    791:          SetWindowText( hWnd, "Waiting for connection..");
                    792: 
                    793: 
                    794:          /*
                    795:          *   Associate an address with a socket. (bind)
                    796:          */
                    797:          if (bind( sock, (struct sockaddr FAR *) &local_sin, sizeof(local_sin)) == SOCKET_ERROR) {
                    798:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    799: 
                    800:             MessageBox(hWnd, szBuff, "bind(sock) failed", MB_OK);
                    801:             break;
                    802:          }
                    803: 
                    804:          if (listen( sock, MAX_PENDING_CONNECTS ) < 0) {
                    805:             sprintf(szBuff, "%d is the error", WSAGetLastError());
                    806: 
                    807:             MessageBox(hWnd, szBuff, "listen(sock) failed", MB_OK);
                    808:             break;
                    809:          }
                    810: 
                    811:          tp.nThread = 0;
                    812:          tp.hWnd = hWnd;
                    813: 
                    814:          _beginthread(AcceptThreadProc, 0, &tp);
                    815: 
                    816:          }
                    817:          break;   /* IDM_TLISTEN */
                    818: 
                    819: 
                    820:       /*
                    821:       *   Display host information.
                    822:       */
                    823:       case IDM_HOSTNAME:
                    824: 
                    825:          /*
                    826:          *  Prompt the user and retrieve the text name of the host.
                    827:          */
                    828:          status = DialogBox(hInst,
                    829:             "HOSTNAME",
                    830:             hWnd,
                    831:             GetHostName);
                    832: 
                    833: 
                    834:          if (status == TRUE) {   /* If user hit "OK" .. */
                    835: 
                    836:          /*
                    837:          *   Get the host information
                    838:          */
                    839: 
                    840:          if ((phe = gethostbyname( szBuff )) == NULL) {
                    841:             MessageBox(hWnd, "gethostbyname() failed", "Error", MB_OK);
                    842:             break;
                    843:          }
                    844:          else {
                    845: 
                    846:          /*
                    847:          *   Display the host information ..
                    848:          */
                    849:             DialogBox(hInst,
                    850:                "DISPLAYHOST",
                    851:                hWnd,
                    852:                DisplayHostEnt);
                    853:          }
                    854:       }
                    855:       break;   /* IDM_HOSTNAME */
                    856:       /*
                    857:       *   Send a message to (via TCP connection) to remote host.
                    858:       */
                    859:       case IDM_SENDTCP:
                    860:          DialogBox(hInst,                /* current instance         */
                    861:             "GetString",                 /* resource to use          */
                    862:             hWnd,                        /* parent handle            */
                    863:             GetSendString);              /* instance address         */
                    864: 
                    865:         /*
                    866:         *   Assumption -- The GetString dialog box proc fills the global
                    867:         *   string buffer, szBuff, with the desired string to send.
                    868:         */
                    869:         send(sock, szBuff, strlen(szBuff), NO_FLAGS_SET );
                    870: 
                    871:         break;   /* IDM_SENDTCP */
                    872: 
                    873: 
                    874: 
                    875:       case IDM_ABOUT:
                    876:          DialogBox(hInst,                /* current instance         */
                    877:             "AboutBox",                  /* resource to use          */
                    878:             hWnd,                        /* parent handle            */
                    879:             About);                      /* About() instance address */
                    880: 
                    881:          break;   /* IDM_ABOUT */
                    882: 
                    883:       default:
                    884:          /* Lets Windows process it          */
                    885:          return (DefWindowProc(hWnd, message, wParam, lParam));
                    886:          break;
                    887:       }
                    888:    break;
                    889: 
                    890: 
                    891:    /*
                    892:    *   Clean up.  Takes care of any open socket descriptors.
                    893:    */
                    894:    case WM_DESTROY:
                    895:       WSACleanup();
                    896:       PostQuitMessage(0);
                    897:       break;
                    898: 
                    899:    default:                       /* Passes it on if unproccessed    */
                    900:       return (DefWindowProc(hWnd, message, wParam, lParam));
                    901: 
                    902:    }
                    903:    return (0);
                    904: 
                    905: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.