home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
215
/
DDJ9302.ZIP
/
SOCKETS.ASC
< prev
next >
Wrap
Text File
|
1993-01-11
|
14KB
|
544 lines
_UNTANGLING THE WINDOWS SOCKETS API_
by Mike Calbaum, Frank Porcaro, Mark Ruegsegger, and Bruce Backman
[LISTING ONE]
/*
* Sock.c -- Windows sockets sample application
*
* Implements psuedo finger client and server.
* Should work with any UNIX finger daemon
*
*/
#include "windows.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <winsock.h>
#include "dlg.h"
#define PROMPT_STRING 130
#define PROMPT_TEXT 131
#define CONN_MSG (WM_USER+25)
#define FNGR_READ (WM_USER+26)
extern void errormsg(LPSTR cp);
extern int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
extern BOOL InitApplication(HANDLE);
extern BOOL InitInstance(HANDLE, int);
extern long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
extern BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);
extern long FAR PASCAL SockWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam);
extern char *prompt(HWND hWnd, HANDLE hInst, char *message, char *buf);
/* Global buffers */
char buff[4096];
char msg[80], name[125];
HANDLE hInst;
HWND hWnd;
struct sockaddr_in anaddr;
int whoport, fngrport; /* Well known port numbers */
int app_closing;
/* Sockets */
SOCKET fclient = INVALID_SOCKET;
SOCKET fserver = INVALID_SOCKET;
SOCKET fconnect = INVALID_SOCKET;
/*
* standard windows initialization routines
*/
BOOL InitApplication(HANDLE hInstance)
{
WNDCLASS wc;
buff[0] = '\0';
wc.style = NULL;
wc.lpfnWndProc = SockWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "SockMenu";
wc.lpszClassName = "SockWClass";
return(RegisterClass(&wc));
}
BOOL InitInstance(HANDLE hInstance, int nCmdShow)
{
hInst = hInstance;
/* Create a main window for this application instance. */
hWnd = CreateWindow("SockWClass", "Sockets Sample Application",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
return (FALSE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return (TRUE);
}
int PASCAL
WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
FARPROC lpfn;
WSADATA wskData;
if (!hPrevInstance)
if (!InitApplication(hInstance))
return(FALSE);
if (!InitInstance(hInstance, nCmdShow))
return(FALSE);
/*
* register application with windows sockets dll
*/
if(!WSAStartup(1, &wskData) && (wskData.wVersion == 1))
{
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (app_closing)
{
/* The application has been requested to shut down. Continue processing
* the close request by calling DestroyWindow */
DestroyWindow(hWnd);
}
}
/* Close any open sockets */
if(fclient != INVALID_SOCKET)
closesocket(fclient);
if(fserver != INVALID_SOCKET)
closesocket(fserver);
if(fconnect != INVALID_SOCKET)
closesocket(fconnect);
/* Let windows sockets know we're done */
WSACleanup();
return(msg.wParam);
}
return(0);
}
BOOL FAR PASCAL About(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if (wParam == IDOK || wParam == IDCANCEL)
{
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
long FAR PASCAL
SockWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
{
int len, cnt;
RECT wRect;
PAINTSTRUCT ps;
HDC hdc;
struct hostent FAR *hp;
static HANDLE arrow, hrGlass, hMenu;
switch (message)
{
case WM_CREATE:
hMenu = GetMenu(hWnd);
arrow = LoadCursor(NULL, IDC_ARROW);
hrGlass = LoadCursor(NULL, IDC_WAIT);
SetCursor(arrow);
break;
/*
* If user presses control-c, interpret as an interrupt request.
* Could also provide a menu item or a dialogbox with a "cancel"
* button.
*
*/
case WM_CHAR:
if (wParam == 3/* ctrl-c */)
{
WSACancelBlockingCall();
strcpy(buff, "Call cancelled!!");
InvalidateRect(hWnd, NULL, 1);
}
else
return(DefWindowProc(hWnd, message, wParam, lParam));
break;
/* Update the window */
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
/* Use fixed fontand expand tabs so tabs align */
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
GetClientRect(hWnd, &wRect);
DrawText(hdc, buff, -1, &wRect, DT_LEFT | DT_EXPANDTABS);
EndPaint(hWnd, &ps);
break;
/* Menu item selected, wParam == menu item ID */
case WM_COMMAND:
switch (wParam)
{
/* Display About Box */
case IDM_ABOUT:
{
FARPROC lpfn;
lpfn = MakeProcInstance(About, hInst);
DialogBox(hInst, "AboutBox", hWnd, lpfn);
FreeProcInstance(lpfn);
break;
}
/* Finger client utility */
case FINGER:
/* Get user name */
if(prompt(hWnd, hInst, "Hostname:", msg) == NULL)
break;
/* Look up the host address */
if((hp = gethostbyname(msg)) == NULL)
{
errormsg("Unknown host");
break;
}
_fmemcpy((char FAR *) &anaddr.sin_addr.s_addr, hp->h_addr, hp->h_length);
/* Get username to finger */
if(!prompt(hWnd, hInst, "Finger User:", msg))
strcpy(msg, "");
/* Look up port number */
if(fngrport == 0)
{
struct servent FAR *sp;
if((sp = getservbyname("finger", "tcp")) == NULL)
{
errormsg("Cannot determine port number for finger daemon.");
break;
}
fngrport = htons(sp->s_port);
}
/* create socket */
if((fclient = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
errormsg("Unable to create a socket");
}
else
{
/* Fill in address to which we will connect */
anaddr.sin_family = PF_INET;
anaddr.sin_port = htons(fngrport);
/* try to connect */
if(connect(fclient, (struct sockaddr FAR *) &anaddr, sizeof(struct sockaddr_in)))
{
errormsg("Unable to connect to finger daemon.");
closesocket(fclient);
fclient = INVALID_SOCKET;
}
else
{
strcat(msg, "\r\n");
if(send(fclient, msg, strlen(msg), 0) < (int) strlen(msg))
{
errormsg("Error sending string to finger daemon");
}
else
if((cnt = recv(fclient, buff, sizeof(buff), 0)) == SOCKET_ERROR)
{
errormsg("Error reading data from daemon");
}
else
if(cnt == 0)
errormsg("No data received from finger daemon");
else
{
buff[cnt] = '\0';
InvalidateRect(hWnd, NULL, 1);
}
}
closesocket(fclient);
fclient = INVALID_SOCKET;
}
break;
case FINGER_SRV:
/* Look up port number */
if(fngrport == 0)
{
struct servent FAR *sp;
if((sp = getservbyname("finger", "tcp")) == NULL)
{
errormsg("Cannot determine port number for finger daemon.");
break;
}
fngrport = htons(sp->s_port);
}
/* if not acting as server, start */
if(fserver == INVALID_SOCKET)
{
/* Get user name */
if(prompt(hWnd, hInst, "Real Name:", msg) == NULL)
break;
else
wsprintf(name, "In Real Life: %s\r\n", (LPSTR) msg);
/* allocate socket */
if((fserver = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
errormsg("Cannot allocate socket for finger server");
break;
}
/* Bind our socket to the finger port number */
anaddr.sin_port = htons(fngrport);
anaddr.sin_addr.s_addr = INADDR_ANY;
anaddr.sin_family = PF_INET;
if(bind(fserver, (struct sockaddr FAR *) &anaddr, sizeof(anaddr)))
{
errormsg("Error binding to finger daemon port");
closesocket(fserver);
fserver = INVALID_SOCKET;
break;
}
/* listen for connections and ask for a message when they come in */
if(listen(fserver, 5) || WSAAsyncSelect(fserver, hWnd, CONN_MSG, FD_ACCEPT))
{
errormsg("Error trying to listen on finger server socket");
closesocket(fserver);
fserver = INVALID_SOCKET;
}
else
CheckMenuItem(hMenu, FINGER_SRV, MF_BYCOMMAND | MF_CHECKED);
}
else /* Already acting as server, stop */
{
closesocket(fserver);
fserver = INVALID_SOCKET;
CheckMenuItem(hMenu, FINGER_SRV, MF_BYCOMMAND | MF_UNCHECKED);
}
break;
case CANCEL: /* Cancel any outstanding blocking call (send or recv) */
WSACancelBlockingCall();
strcpy(buff, "Call cancelled!!");
InvalidateRect(hWnd, NULL, 1);
break;
case QUIT:
SendMessage(hWnd, WM_CLOSE, 0, 0L);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case CONN_MSG: /* Connection on finger server */
if(WSAGETSELECTERROR(lParam))
errormsg("Error listening for finger connections");
else
{
/* accept connection */
len = sizeof(struct sockaddr_in);
fconnect = accept(fserver, (struct sockaddr FAR *) &anaddr, &len);
if(fconnect == INVALID_SOCKET)
errormsg("Error accepting connection to finger server");
else
WSAAsyncSelect(fconnect, hWnd, FNGR_READ, FD_READ);
}
break;
case FNGR_READ: /* Data available for reading */
{
/* The finger client will send us a string but we will ignore it */
cnt = recv(fconnect, buff, sizeof(buff), 0);
buff[0] = '\0';
if(cnt == SOCKET_ERROR)
errormsg("Error reading from finger client");
else
if(send(fconnect, name, strlen(name), 0) < (int) strlen(name))
errormsg("Error sending data to finger client");
/* Close up the accepted connection */
closesocket(fconnect);
fconnect = INVALID_SOCKET;
}
break;
case WM_CLOSE:
/* Application's main window is closing. Set flag to notify main loop
* The main function is responsible for handling the close
*/
app_closing = 1;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (NULL);
}
char PromptText[41]; /* prompt message text for prompt dlg */
char PromptString[81]; /* user's input from prompt dlg */
/*
* PromptDlgProc - Processes the "prompt" dialog box
*
* globals: PromptText - prompt message text
* PromptString - user's input
* return: IDOK or IDCANCEL
*/
BOOL FAR PASCAL
PromptDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
switch (message)
{
case WM_COMMAND:
if (wParam == IDOK)
{
GetDlgItemText(hDlg, PROMPT_STRING, PromptString, 80);
EndDialog(hDlg, IDOK);
return TRUE;
}
else if (wParam == IDCANCEL)
{
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
break;
case WM_INITDIALOG:
SetDlgItemText(hDlg, PROMPT_TEXT, PromptText);
return(TRUE);
break;
default:
return FALSE;
}
}
/*
* prompt - displays message, copies user response into buf
*
* return: NULL for cancel, or FAR * to buf
*/
char *prompt(HWND hWnd, HANDLE hInst, char *message, char *buf)
{
int rc;
FARPROC lpDlgProc;
lstrcpy(PromptText, message);
lpDlgProc = MakeProcInstance(PromptDlgProc, hInst);
rc = DialogBox(hInst, "PROMPT", hWnd, lpDlgProc);
FreeProcInstance(lpDlgProc);
if (rc == IDOK)
lstrcpy(buf, PromptString);
else
buf = NULL;
return buf;
}
/*
* errormsg - displays an error message and the last error
*
*/
void errormsg(LPSTR cp)
{
char buf[128];
wsprintf(buf, "%s (%d)", (LPSTR)cp, WSAGetLastError());
MessageBox(hWnd, buf, NULL, MB_ICONHAND);
}
[LISTING TWO]
#define FINGER 112
#define FINGER_SRV 113
#define CANCEL 114
#define IDM_ABOUT 115
#define QUIT 116
#define PROMPT_STRING 130
#define PROMPT_TEXT 131
[LISTING THREE]
#include "windows.h"
#include "dlg.h"
#include "sock.dlg"
SockMenu MENU
BEGIN
POPUP "&Sockets"
BEGIN
MENUITEM "Finger &Client", FINGER
MENUITEM "&Finger Server...", FINGER_SRV
MENUITEM "&Cancel Operation", CANCEL
MENUITEM "A&bout...", IDM_ABOUT
MENUITEM "&Quit", QUIT
END
END