/*---------------------------------------------------------------------
*
* 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 <windows.h>
#include <windowsx.h>
#include <winsock.h>
#include "..\winsockx.h"
#include "..\wsa_xtra.h"
#include <string.h> /* 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 */
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 copy 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() */
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];