📄 sdkclient.cpp
字号:
// Api_test.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include <memory.h>
#include <string.h>
#include "winecho.h"
//一些变量
HANDLE hInst,AsyncHnd;
char buffer[2]={0,0};
int col=0,row=0;
struct sockaddr_in dst_addr;
char FAR * lpBuffer = &buffer[0];
SOCKET s = 0;
int connected = 0;
unsigned short port=5050;
int sock_type=SOCK_STREAM;
//函数的声明
BOOL InitWindow(HINSTANCE); //[1],实现见[1]
long FAR PASCAL ClientProc(HWND, unsigned, UINT, LONG); //[2],实现见[2]
BOOL Client(HWND hWnd); //[3],实现见[3]
BOOL set_select(HWND, long);//[4],实现见[4]
BOOL make_skt(HWND);//[5],实现见[5]
BOOL connect_skt(HWND);//[6],实现见[6]
BOOL send_pkt(HWND,int);//[7],实现见[7]
int receive_pkt(HWND);//[8],实现见[8]
void close_skt(void);//[9],实现见[9]
void DisplayInfo(HWND,int);//[10],实现见[10]
void MessageToUser(HWND, LPSTR); //[11],实现见[11]
//Winmain()函数
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd;
MSG msg;
if (!hPrevInstance)
if (!InitWindow(hInstance)) //初始化窗口
return (FALSE);
hInst = hInstance;
//初始化窗口
hWnd = CreateWindow("ClientClass",
"Windows ECHO Client",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
return (FALSE);
ShowWindow(hWnd, nCmdShow); //显示窗口
UpdateWindow(hWnd);
EnableMenuItem(GetMenu(hWnd),IDM_EXIT,MF_DISABLED|MF_GRAYED);
//发送自定义消息WM_USER
PostMessage(hWnd, WM_USER, (WPARAM)0, (LPARAM)0);
//消息队列的循环
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
//实现[1]:初始化窗口类
BOOL InitWindow(HINSTANCE hInstance)
{
WNDCLASS WndClass;
char *szAppName = "ClientClass";
WndClass.lpszClassName = (LPSTR)szAppName;
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = ClientProc;
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon =LoadIcon(NULL,IDI_APPLICATION);
WndClass.lpszMenuName =(LPSTR) "EchoMenu";
WndClass.lpszClassName =(LPSTR)"ClientClass";
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
//注册窗口类
if (!RegisterClass(&WndClass))
return(FALSE);
return(TRUE);
}
//实现[2]:回调函数,实现见最后
//实现[3]:客户程序创建socket并建立连接
BOOL Client(HWND hWnd)
{
EnableMenuItem(GetMenu(hWnd),IDM_START,MF_ENABLED);
EnableMenuItem(GetMenu(hWnd),IDM_EXIT,MF_ENABLED);
if(!make_skt(hWnd)) //创建socket
{
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);
}
//实现[4]:异步选择子程序
BOOL set_select(HWND hWnd, long lEvent)
{
if (WSAAsyncSelect(s, hWnd, UM_SOCK, lEvent) == SOCKET_ERROR)
{
MessageToUser(hWnd, "WSAAsyncSelect Failure.");
return (FALSE);
}
return (TRUE);
}
//实现[5]:创建socket函数
BOOL make_skt(HWND hWnd)
{
if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
MessageToUser(hWnd, "Socket Failed");
return (FALSE);
}
return (TRUE);
}
//实现[6]:发送数据的函数
BOOL send_pkt(HWND hWnd, int len)
{
int length;
if ((length = send(s, lpBuffer, len, 0)) == SOCKET_ERROR)
{
MessageToUser(hWnd,"Send Failed");
close_skt();
return(FALSE);
}
if (length != len)
{
MessageToUser(hWnd, "Send Length NOT Match!");
close_skt();
return (FALSE);
}
return (TRUE);
}
//实现[7]:建立连接子程序
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(5050);//USERPORT=5050;
dst_addr.sin_addr.S_un.S_un_b.s_b1=202;
dst_addr.sin_addr.S_un.S_un_b.s_b2=115;
dst_addr.sin_addr.S_un.S_un_b.s_b3=111;
dst_addr.sin_addr.S_un.S_un_b.s_b4=222;
if(connect(s, (struct sockaddr *)&dst_addr, sizeof(dst_addr))==SOCKET_ERROR)
{
errno=WSAGetLastError();
if(errno!=WSAEWOULDBLOCK)
{
MessageToUser(hWnd,"Connect Failed");
close_skt();
return(FALSE);
}
}
return(TRUE);
}
//实现[8]:接收数据的函数
int receive_pkt(HWND hWnd)
{
int errno,length,len;
length=1024;
if ((len = recv(s, lpBuffer, 1024, 0)) == SOCKET_ERROR)//接收网络数据
{
errno=WSAGetLastError();
if(errno==WSAEWOULDBLOCK)
return(TRUE);
MessageToUser(hWnd,"Received Failed");
close_skt();
return (FALSE);
}
length=len;
if (length == 0)
{
MessageToUser(hWnd,"Connection was Closed");
close_skt();
}
return(length);
}
//实现[9]:关闭Socket
void close_skt()
{
if(s)
{
(void)closesocket(s);
s=0;
}
}
//实现[10]:显示接收数据子程序
void DisplayInfo(HWND hWnd,int len)
{
HDC dc;
int l;
char line[16];
buffer[len]=0;
if (dc = GetDC(hWnd))
{
l= wsprintf((LPSTR)line, "%s", lpBuffer);
TextOut(dc, 10*col, 16*row, (LPSTR)line,l);
ReleaseDC(hWnd, dc);
}
col+=len;
if(col>40)
{
col=0;
row++;
}
}
//实现[11]:给用户提示信息
void MessageToUser(HWND hWnd, LPSTR lpszWarning)
{
MessageBox(hWnd, lpszWarning, "Warning", MB_ICONEXCLAMATION);
return;
}
//回调函数
long FAR PASCAL ClientProc(HWND hWnd, unsigned message, UINT wParam, LONG lParam)
{
int length;
WSADATA wsaData;
LPSTR msgstr;
int Status;
switch (message)
{
//分支1
case WM_USER: //用户初始化消息,启动Windows Sockets DLL,协商版本支持
Status = WSAStartup(0x101, &wsaData);
if (Status != 0)
{
MessageToUser(hWnd, "WSAStartup() failed\n");
PostQuitMessage(0);
}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
MessageToUser(hWnd,"WSAStartup() failed \n");
WSACleanup();
PostQuitMessage(0);
}
break;
//分支2
case WM_COMMAND:
switch (wParam)
{
case IDM_START:
if (!Client(hWnd))
{
MessageToUser(hWnd, "Start Failed");
EnableMenuItem(GetMenu(hWnd),IDM_START,
MF_ENABLED);
EnableMenuItem(GetMenu(hWnd),IDM_EXIT,
MF_DISABLED|MF_GRAYED);
}
else
{
EnableMenuItem(GetMenu(hWnd),IDM_START,
MF_DISABLED|MF_GRAYED);
EnableMenuItem(GetMenu(hWnd),IDM_EXIT,
MF_ENABLED);
}
break;
case IDM_EXIT:
//退出前注销对Windows Sockets DLL的使用
WSACleanup();
PostQuitMessage(0);
break;
}
break;
//分支3
case WM_CHAR:
if(wParam=='q'||wParam=='Q')
{
PostMessage(hWnd,WM_COMMAND,(WPARAM)IDM_EXIT,(LPARAM)0);
break;
}
PostMessage(hWnd,UM_SOCK,(WPARAM)wParam,(LPARAM)FD_USERWRITE);
break;
//分支4
case UM_SOCK: //异步选择消息
switch (lParam)
{
case FD_CONNECT: //连接建立完成,置标志
connected=1;
break;
case FD_READ: //数据读准备好,读数据并显示
if ((length=receive_pkt(hWnd))==0)
{
MessageToUser(hWnd, "Receive Packet Failed.\n");
close_skt();
break;
}
DisplayInfo(hWnd,length);
break;
//写准备好,此中没有进行数据的发送,因为下面的FD_USERWRITE处理中进行了
case FD_WRITE:
break;
case FD_USERWRITE: //用户写数据消息,发送数据
if(!connected)
{
MessageToUser(hWnd,"Connection not created!");
break;
}
length=1;
buffer[0]=(char)wParam;
//只是发送了一个字节
if(!(send_pkt(hWnd,length)))
{
MessageToUser(hWnd, "Packet Send Failed.\n");
close_skt();
break;
}
break;
default:
if (WSAGETSELECTERROR(lParam) != 0)
{
MessageToUser(hWnd, "Socket Report Failure.");
close_skt();
break;
}
sprintf(msgstr,"lParam=0x%lx,wParam=0x%x",lParam,wParam);
MessageToUser(hWnd,msgstr);
break;
}
break;
//分支5
case WM_DESTROY:
close_skt();
WSACleanup();
PostQuitMessage(0);
break;
//分支6
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return(NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -