2000 /*--------------------------------------------------------------------- * * Program: WSASIMPL DLL Test Client * * filename: simpltst.c * * copyright by Bob Quinn, 1995 * * Description: * This application uses the simplified WinSock API provided by the * sample WSASIMPL dynamic link library. It connects to the echo * port, sends a string of characters, then reads them back and * displays them. * * This software is not subject to any export provision of * the United States Department of Commerce, and may be * exported to any country or planet. * * Permission is granted to anyone to use this software for any * purpose on any computer system, and to alter it and redistribute * it freely, subject to the following restrictions: * * 1. The author is not responsible for the consequences of * use of this software, no matter how awful, even if they * arise from flaws in it. * * 2. The origin of this software must not be misrepresented, * either by explicit claim or by omission. Since few users * ever read sources, credits must appear in the documentation. * * 3. Altered versions must be plainly marked as such, and * must not be misrepresented as being the original software. * Since few users ever read sources, credits must appear in * the documentation. * * 4. This notice may not be removed or altered. * ---------------------------------------------------------------------*/ #include "wsasimpl.h" #include #include #include #include "..\winsockx.h" #include "..\wsa_xtra.h" #include /* for _fmemcpy() & _fmemset() */ #include "resource.h" /*------------ global variables ------------*/ char szAppName[] = "simpltst"; #define MY_BUF_SIZE 2048 #define MY_TIMEOUT 10000 SOCKET hSock = INVALID_SOCKET; /* Socket */ char achInBuf [MY_BUF_SIZE]; /* Input Buffer */ char szHost [MAXHOSTNAME]; /* Echo Server to connect to */ int wChargenLen = MY_BUF_SIZE; /* length of string to be output */ char achChargenBuf[MY_BUF_SIZE]; /* we put CHARGEN_SEQ string resource here */ int cbBufSize; long cbBytesToSend = 1048576; /* 1 Megabyte */ /* display buffer (8K) */ #define DISP_LINE_LEN 128 #define DISP_NUM_LINES 64 #define DISP_BUFSIZE DISP_LINE_LEN * DISP_NUM_LINES HANDLE hInst; HWND hWinMain; LONG WINAPI WndProc (HWND, UINT, WPARAM,LPARAM); BOOL WINAPI Dlg_Host (HWND,UINT,UINT,LONG); /*-------------------------------------------------------------------- * Function: WinMain() * * Description: initialize and start message loop */ int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { MSG msg; WNDCLASS wc; lpszCmdLine = lpszCmdLine; /* avoid warning */ hInst = hInstance; /* Save instance handle */ if (!hPrevInstance) { /* register window class */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst, (LPCSTR)SIMPLTST); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = COLOR_WINDOW+1; wc.lpszMenuName = MAKEINTRESOURCE(SIMPLTST); wc.lpszClassName = szAppName; if (!RegisterClass (&wc)) { return (0); } } hWinMain = CreateWindow( szAppName, "Simple Echo Client", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL ); if (!hWinMain) return (0); ShowWindow(hWinMain, nCmdShow); UpdateWindow(hWinMain); while (GetMessage (&msg, NULL, 0, 0)) { /* main loop */ TranslateMessage(&msg); DispatchMessage (&msg); } return msg.wParam; } /* end WinMain() */ /*-------------------------------------------------------------------- * Function: WndProc() * * Description: Main window's message processor. */ LONG CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL bRet; switch (msg) { case WM_COMMAND: switch (wParam) { case IDM_CONNECT: if (hSock == INVALID_SOCKET) { bRet = DialogBox (hInst, MAKEINTRESOURCE(IDD_HOST), hwnd, Dlg_Host); if (bRet) { hSock = ConnectTCP ((LPSTR)szHost, (LPSTR)"echo"); if (hSock != INVALID_SOCKET) { wsprintf (achTempBuf, "ConnectTCP() returned Socket %d", hSock); MessageBox (hwnd, achTempBuf, "ConnectTCP()", MB_OK); } } else { MessageBox (hwnd, "Need a destination host to connect to", "Can't connect!", MB_OK | MB_ICONASTERISK); } } else { MessageBox (hwnd, "You already have a connection open", "Can't connect!", MB_OK | MB_ICONASTERISK); } break; case IDM_START: if (hSock == INVALID_SOCKET) { MessageBox (hwnd, "You need to connect first", "Can't start sending!", MB_OK | MB_ICONASTERISK); } else { HDC hdc = GetDC(hwnd); int nRet = 1, i; long cbBytesSent = 0L; for (i=40;i;i--) TextOut(hdc,(6*i),50," ",2); TextOut(hdc,10,10,"Now sending and receiving 1 megabyte",36); /*----------------------------------------------------------- * Note: due to subclassing that prevents "reentrant" * mouse and keyboard messages, the user cannot interact * with the program while this send/receive loop executes. -----------------------------------------------------------*/ while (nRet && (nRet != SOCKET_ERROR)) { nRet = SendData(hSock, achChargenBuf, MY_BUF_SIZE); if (nRet && (nRet != SOCKET_ERROR)) { cbBytesSent += nRet; nRet = RecvData(hSock, achInBuf, MY_BUF_SIZE, MY_TIMEOUT); TextOut(hdc,10+(6*i),30,">",1); if (i++ > 40) { for (;i;i--) TextOut(hdc,5+(6*i),30," ",2); } } if (cbBytesSent >= cbBytesToSend) break; } if (nRet && (nRet != SOCKET_ERROR)) TextOut(hdc,10,50,"Send and receive complete!",26); ReleaseDC(hwnd, hdc); } break; case IDM_CLOSE: if (hSock != INVALID_SOCKET) { CloseTCP(hSock, 0, 0); wsprintf (achTempBuf, "Connection on socket %d is now closed", hSock); MessageBox (hwnd, achTempBuf, "CloseTCP()", MB_OK); hSock = INVALID_SOCKET; } else { MessageBox (hwnd, "No open connection to close", "Can't close!", MB_OK | MB_ICONASTERISK); } break; case IDM_ABOUT: DialogBox (hInst, MAKEINTRESOURCE(IDD_ABOUT), hwnd, Dlg_About); break; case IDM_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0L); break; } /* end case WM_COMMAND: */ break; case WM_CREATE: /*------------load string into our work buffer---------- */ cbBufSize = LoadString (hInst, CHARGEN_SEQ, achInBuf, MY_BUF_SIZE); if (cbBufSize) { /* get our char string */ int i,j; /* number of iterations we need to cop c2f y string */ i = (MY_BUF_SIZE) / cbBufSize; /* fill chargen buf w/ repeated char series */ for (j=0; i > 0; i--, j+=cbBufSize) { _fmemcpy((LPSTR)&(achChargenBuf[j]), (LPSTR)achInBuf, cbBufSize); } /* to finish, fill remainder of buffer (if any) */ i = (MY_BUF_SIZE) % cbBufSize; if (i) { j = ((MY_BUF_SIZE) / cbBufSize) * cbBufSize; _fmemcpy ((LPSTR)&(achChargenBuf[j]), (LPSTR)achInBuf, i); } } /* center dialog box */ CenterWnd (hwnd, NULL, TRUE); break; case WM_CLOSE: if (hSock != INVALID_SOCKET) { CloseTCP(hSock, 0, 0); } DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hwnd, msg, wParam, lParam)); } /* end switch (msg) */ return 0; } /* end WndProc() */ /*--------------------------------------------------------------------- * Function: Dlg_Host() * * Description: Prompt user for destination host or address. */ BOOL WINAPI Dlg_Host ( HWND hDlg, UINT msg, UINT wParam, LPARAM lParam) { BOOL bRet = FALSE; lParam = lParam; /* avoid warning */ switch (msg) { case WM_INITDIALOG: /* set display values */ SetDlgItemText (hDlg, IDC_HOST, szHost); SetFocus (GetDlgItem (hDlg, IDC_HOST)); /* center dialog box */ CenterWnd (hDlg, NULL, TRUE); break; case WM_COMMAND: switch (wParam) { case IDOK: GetDlgItemText (hDlg, IDC_HOST, szHost, MAXHOSTNAME); EndDialog (hDlg, TRUE); bRet = TRUE; break; case IDCANCEL: EndDialog (hDlg, FALSE); bRet = FALSE; break; default: break; } } return (bRet); } /* end Dlg_Host() */ /*--------------------------------------------------------------------- * Function: Dlg_About() * * Description: Dialog procedure for About box. We cannot use our * WinSockx library Dlg_About() procedure because we don't have * a WSAData structure to display (we don't call WSAStartup(), * but the WSASIMPL DLL does). */ BOOL FAR PASCAL Dlg_About ( HWND hDlg, UINT msg, UINT wParam, LONG lParam) { char achDataBuf[WSADESCRIPTION_LEN+1]; lParam = lParam; /* avoid warning */ switch (msg) { case WM_INITDIALOG: wsprintf (achDataBuf, "(Compiled: %s, %s)\n", (LPSTR)__DATE__, (LPSTR)__TIME__); SetDlgItemText (hDlg, IDC_COMPILEDATE, (LPCSTR)achDataBuf); /* center dialog box */ CenterWnd (hDlg, NULL, TRUE); return FALSE; case WM_COMMAND: switch (wParam) { case IDOK: EndDialog (hDlg, 0); return TRUE; } break; } return FALSE; } /* end Dlg_About() */ . 0