直接用Windows Socket API编程遇到的问题。
我Winsock的代码都在WndProc函数里,其他代码都是Win32窗体应用程序的标准代码,由新建工程时的向导(不是MFC向导)自动创建的,包括WinMain,注册窗口类之类的函数。说明清楚工程的类型,就不必多介绍了。
我现在写好的程序都不会报错,存在的疑问只是对于建立连接的流程和代码的编写有一些疑问。
先给出服务器的WndProc的代码(其他都是标准的,就省略了)。下面再说疑问。
/*事先定义了其中所有要用到的变量,以及
#define OnMySocketMessage 111111
为监听Socket对象的消息;
#define OnAcceptSocket 222222
为用于连接的Socket对象的消息
*/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
//RECT r;
//TCHAR text[] = _T("");
switch (message)
{
case WM_CREATE:
//-----------------------------------------
//-------------Winsock内容-----------------
//-----------------------------------------
// 初始化WinSock
WSAStartup((WORD)(1<<8|1),&WSAData);
//建立侦听所用的socket
MySocket = socket(PF_INET,SOCK_STREAM,0);
//绑定端口
memset(&MyName,0,sizeof(MyName));//初始化mysock结构体名
MyName.sin_addr.s_addr=htonl(INADDR_ANY);//IP地址。#define s_addr S_un.S_addr
MyName.sin_family=AF_INET;//只能是这个值
MyName.sin_port=htons(1024);//端口
bind(MySocket,(sockaddr *) &MyName,sizeof(MyName));//绑定端口
//侦听
listen(MySocket,3);
//注册连接消息回调
WSAAsyncSelect(MySocket,hWnd,OnMySocketMessage, FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);//希望套接字在收到请求时产生消息
//-----------------------------------------
//-------------Winsock内容完---------------
//-----------------------------------------
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//绘图或文本输出代码
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
closesocket(MySocket);
closesocket(AcceptSocket);
WSACleanup();
PostQuitMessage(0);
break;
case OnMySocketMessage://套接字消息
switch(lParam)
{
case FD_ACCEPT://收到连接请求
CustomNameLen=sizeof(CustomName);
AcceptSocket = accept(MySocket,(sockaddr *)&CustomName,&CustomNameLen);//相应连接
WSAAsyncSelect(AcceptSocket,hWnd,OnAcceptSocket, FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);//希望套接字在收到请求时产生消息
break;
case FD_CONNECT://连接成功
break;
case FD_CLOSE://连接关闭
closesocket(MySocket);//关闭连接
WSACleanup();
break;
}
case OnAcceptSocket:
switch(lParam)
{
case FD_READ://收到数据
char text[225];
recv(MySocket,&text[0],sizeof(text),0);
break;
case FD_WRITE://发送数据
break;
case FD_OOB://收到带外数据
break;
case FD_ACCEPT://收到连接请求
break;
case FD_CONNECT://连接成功
break;
case FD_CLOSE://连接关闭
closesocket(MySocket);//关闭连接
WSACleanup();
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
现在,我先启动服务器,在启动客户端,在客户端启动成功之后,服务器的MySocket(用于侦听的的Socket)收到lParam包含FD_ACCEPT的OnMySocketMessage消息。我按照上面所说的调用accept来响应,也要调用WSAAsyncSelect函数,以返回的AcceptSocket为参数注册他的网络消息回调(如代码)。执行了之后随即收到OnAcceptSocket消息,但是lParam中包含的值是8.不是上面定义的FD_READ等6个常数中的任何一个?这是怎么回事?
客户端这边跟服务器很相似(准确说客户端就是服务器的项目复制了一份改过来的),照贴代码吧,客户端的问题不多,就是……那个该死的消息从头到尾一次都没收到过
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
char text[]={"My infomation"};
switch (message)
{
case WM_CREATE:
//-----------------------------------------
//-------------Winsock内容-----------------
//-----------------------------------------
// 初始化WinSock
WSAStartup((WORD)(1<<8|1),&WSAData);
//建立侦听所用的socket
MySocket = socket(PF_INET,SOCK_STREAM,0);
//绑定端口
memset(&MyName,0,sizeof(MyName));//初始化mysock结构体名
MyName.sin_addr.s_addr=inet_addr("127.0.0.1");//IP地址。#define s_addr S_un.S_addr
MyName.sin_family=AF_INET;//只能是这个值
MyName.sin_port=htons(1024);//端口
//连接
connect(MySocket,(sockaddr *) &MyName,sizeof(MyName));
//注册连接消息回调
WSAAsyncSelect(MySocket,hWnd,OnMySocketMessage, FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE);//希望套接字在收到请求时产生消息
//-----------------------------------------
//-------------Winsock内容完---------------
//-----------------------------------------
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//绘图或文本输出代码
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
closesocket(MySocket);
WSACleanup();
PostQuitMessage(0);
break;
case OnMySocketMessage://套接字消息
switch(lParam)
{
case FD_READ://收到数据
break;
case FD_WRITE://发送数据
break;
case FD_OOB://收到带外数据
break;
case FD_ACCEPT://收到连接请求
break;
case FD_CONNECT://连接成功
send(MySocket,&text[0],sizeof(text),0);
break;
case FD_CLOSE://连接关闭
closesocket(MySocket);//关闭连接
WSACleanup();
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}