|
|
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.