long FAR PASCAL
ClientProc( HWND hWnd, unsigned message, UINT
wParam, LONG lParam)
{
int length;
WSADATA
wsaData;
int Status;
LPSTR
msgstr;
switch
(message) {
case
WM_USER:// 用户初始化消息。启动Windows
Sockets DLL,协商版本支持。
Status
= WSAStartup(0x101, &wsaData);
if
(Status != 0) {
AlertUser(hWnd,
"WSAStartup() failed \n");
PostQuitMessage(0);
}
if
(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion)
!= 1) {
AlertUser(hWnd,
"WSAStartup() Version not match\n");
WSACleanup();
PostQuitMessage(0);
}
//通过主机名异步获取主机信息。
AsyncHnd
= WSAAsyncGetHostByName(hWnd, UM_REQ,
server_address,
buffer, MAXGETHOSTSTRUCT);
break;
case
WM_COMMAND:
switch
(wParam) {
case
IDM_START:
if
(!Client(hWnd)) {
AlertUser(hWnd,
"Start Failed");
EnableMenuItem(GetMenu(hWnd),
IDM_START, MF_ENABLED);
EnableMenuItem(GetMenu(hWnd),IDM_STOP,
MF_DISABLED|MF_GRAYED);
}
else
{
EnableMenuItem(GetMenu(hWnd),
IDM_START,
MF_DISABLED
| MF_GRAYED);
EnableMenuItem(GetMenu(hWnd),
IDM_STOP, MF_ENABLED);
}
break;
case
IDM_STOP:
WSACleanup(); //退出前注销对Windows Sockets DLL的使用。
PostQuitMessage(0);
break;
}
break;
case
WM_CHAR:
if
(wParam == 'q' | wParam == 'Q') {
PostMessage(hWnd,
WM_COMMAND, (WPARAM)IDM_STOP, (LPARAM)0);
break;
}
PostMessage(hWnd,
UM_SOCK,(WPARAM)wParam, (LPARAM)FD_USERWRITE);
break;
case
UM_REQ: //异步请求完成消息,结果在缓冲区中。
if
(WSAGETASYNCERROR(lParam)) {
AlertUser(hWnd,
"WSAAsyncGetHostByName ERROR \n");
WSACleanup();
PostQuitMessage(0);
}
memcpy(&hostnm,
lpBuffer, sizeof(struct hostent));
break;
case
UM_SOCK: //异步选择消息。
switch
(lParam) {
case
FD_CONNECT: //连接建立完成,置标志。
connected
= 1;
break;
case
FD_READ: //数据读准备好,读数据并显示。
if
((length = receive_pkt(hWnd)) == 0)
{
AlertUser(hWnd,
"Receive Packet Failed");
close_skt();
break;
}
DisplayInfo(hWnd,
length);
break;
case
FD_WRITE: //写准备好。
break;
case
FD_USERWRITE: //用户写数据消息,发送数据。
if
(!connected) {
AlertUser(hWnd,
"Connection not created");
break;
}
length
= 1;
buffer[0]
= (char)wParam;
if (!(send_pkt(hWnd, length))) {
AlertUser(hWnd,
"Packet Send Failed");
close_skt();
break;
}
break;
case
FD_CLOSE: //连接关闭,置标志。
connected
= 0;
if
(WSAAsyncSelect(s,hWnd,0,0) == SOCKET_ERROR)
AlertUser(hWnd,
"WSAAsyncSelect Failed");
AlertUser(hWnd,
"Socket has been closed");
EnableMenuItem(GetMenu(hWnd),IDM_START,
F_ENABLED);
EnableMenuItem(GetMenu(hWnd),
IDM_STOP, MF_DISABLED |
MF_GRAYED);
break;
default:
if
(WSAGETSELECTERROR(lParam) != 0) {
AlertUser(hWnd,
"Socket Report Failure");
close_skt();
break;
}
sprintf(msgstr,
"lParam = 0x%lx, wParam = 0x%x",lParam,wParam);
AlertUser(hWnd,
msgstr);
break;
}
break;
case
WM_DESTROY:
close_skt();
WSACleanup(); //退出前注销对Windows Sockets DLL的使用。
PostQuitMessage(0);
break;
default:
return
(DefWindowProc(hWnd, message, wParam, lParam));
}
return
(NULL);
}
VOID //报警子程序。
AlertUser( HWND hWnd, LPSTR lpszWarning )
{
MessageBox(hWnd,
lpszWarning, "Windows Client", MB_OK | MB_ICONEXCLAMATION);
}
/****************************************************************************/
BOOL //客户程序创建套接字并建立连接。
Client( HWND hWnd )
{
EnableMenuItem(GetMenu(hWnd),
IDM_START, MF_ENABLED);
EnableMenuItem(GetMenu(hWnd),
IDM_STOP, MF_ENABLED);
if
(!make_skt(hWnd)) { //创建套接字。
close_skt();
return(FALSE);
}
if (!set_select(hWnd, FD_CONNECT | FD_READ | FD_WRITE)) {//异步选择网络事件。
close_skt();
return(FALSE);
}
if
(!connect_skt(hWnd)) { //建立连接。
close_skt();
return(FALSE);
}
return(TRUE);
}
/****************************************************************************/
int //接收数据子程序。
receive_pkt(HWND hWnd)
{
int errno, length, len;
length
= 1024;
if ((len = recv(s, lpBuffer,
length, 0)) == SOCKET_ERROR) { //接收网络数据。
errno
= WSAGetLastError();
if
(errno==WSAEWOULDBLOCK)
return(TRUE);
AlertUser(hWnd,
"Received Failed");
close_skt();
return(FALSE);
}
length
= len;
if (length == 0) {
AlertUser(hWnd,
"Connection was Closed");
close_skt();
}
return(length);
}
BOOL //异步选择子程序。
set_select( HWND hWnd, long lEvent)
{
if (WSAAsyncSelect(s,
hWnd, UM_SOCK, lEvent) == SOCKET_ERROR) {
AlertUser(hWnd,
"WSAAsyncSelect Failed");
return
(FALSE);
}
return (TRUE);
}
BOOL //创建套接字子程序。
make_skt( HWND hWnd )
{
if ((s = socket(AF_INET, sock_type, 0)) == INVALID_SOCKET) {
AlertUser(hWnd,
"Socket Failed");
return
(FALSE);
}
return (TRUE);
}
BOOL //建立连接子程序。
connect_skt( HWND hWnd )
{
int
errno;
memset((void *) &dst_addr,
sizeof(dst_addr), 0);
dst_addr.sin_family = AF_INET;
dst_addr.sin_port = htons(port);
dst_addr.sin_addr.s_addr
= *((unsigned long *)hostnm.h_addr_list[0]);
if (connect(s, (struct
sockaddr *) & dst_addr, sizeof(dst_addr)) == SOCKET_ERROR) {
errno
= WSAGetLastError();
if
(errno != WSAEWOULDBLOCK) {
AlertUser(hWnd,
"Connect Failed");
close_skt();
return
(FALSE);
}
}
return (TRUE);
}
B