|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.