一个很简单的练习程序,调试了一天,就是不知道到底错在哪。程序是测试WSAAsyncSelect模式的。话不多说,先上代码:服务端代码:
#define WM_SOCKET WM_USER+101
#include <WINSOCK2.H>
/*#include <windows.h>*/
#pragma comment(lib,"WS2_32")
//----------------窗口过程函数的声明-------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//----------------WinMain()函数------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
WNDCLASS wc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WindowProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_EXCLAMATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName="Test";
//---注册窗口类----
RegisterClass(&wc);
//---创建窗口----
HWND hwnd=CreateWindow("Test","窗口标题",WS_SYSMENU,300,0,600,400,NULL,NULL,hInstance,NULL);
if (hwnd==NULL)
{
MessageBox(hwnd,"创建窗口出错","标题栏提升",MB_OK);
return 1;
}
//---显示窗口----
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//---socket-----
WSADATA wsaData;
WORD wVersionRequested=MAKEWORD(2,2);
if (WSAStartup(wVersionRequested,&wsaData)!=0)
{
MessageBox(NULL,"WSAStartup() Failed","调用失败",0);
return 1;
}
SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s==INVALID_SOCKET)
{
MessageBox(NULL,"socket() Failed","调用失败",0);
return 1;
}
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(4567);
sin.sin_addr.S_un.S_addr=INADDR_ANY;
if (bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
MessageBox(NULL,"bind() Failed","调用失败",0);
return 1;
}
if (listen(s,3)==SOCKET_ERROR)
{
MessageBox(NULL,"listen() Failed","调用失败",0);
return 1;
}
else
MessageBox(hwnd,"进入监听状态!","标题栏提示",MB_OK);
if(WSAAsyncSelect(s,hwnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR)
{
MessageBox(hwnd,"Can not register message", "" ,MB_OK);
return 0;
}
//---消息循环----
// SendMessage(hwnd , WM_SOCKET , 0 , 0);
MSG msg;
while (GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
closesocket(s);
WSACleanup();
return msg.wParam;
}
//-------------------窗口过程----------------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SOCKET:
{
SOCKET ss=wParam; //wParam参数标志了网络事件发生的套接口
if (WSAGETSELECTERROR(lParam))
{
closesocket(ss);
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: //-----①连接请求到来
{
sockaddr_in Cadd;
int Cadd_len=sizeof(Cadd);
SOCKET sNew=accept(ss,(sockaddr*)&Cadd,&Cadd_len);
if (ss==INVALID_SOCKET)
MessageBox(hwnd,"调用accept()失败!","标题栏提示",MB_OK);
WSAAsyncSelect(sNew,hwnd,WM_SOCKET,FD_READ|FD_CLOSE);
}break;
case FD_READ: //-----②数据发送来
{
MessageBox(hwnd,"调用accept()失败!","标题栏提示",MB_OK);
char cbuf[256];
memset(cbuf,0,256);
int cRecv=recv(ss,cbuf,256,0);
if ((cRecv==SOCKET_ERROR&& WSAGetLastError() == WSAECONNRESET)|| cRecv==0)
{
MessageBox(hwnd,"调用recv()失败!","标题栏提示",MB_OK);
closesocket(ss);
}
else if (cRecv>0)
{
MessageBox(hwnd,cbuf,"收到的信息",MB_OK);
char Sbuf[]="Hello client!I am server";
int isend=send(ss,Sbuf,sizeof(Sbuf),0);
if (isend==SOCKET_ERROR || isend<=0)
{
MessageBox(hwnd,"发送消息失败!","标题栏提示",MB_OK);
}
else
MessageBox(hwnd,"已经发信息到客户端!","标题栏提示",MB_OK);
}
}break;
case FD_CLOSE: //----③关闭连接
{
closesocket(ss);
}
break;
default:
MessageBox(hwnd,"default!","标题栏提示",MB_OK);
}
}
break;
case WM_CLOSE:
if (IDYES==MessageBox(hwnd,"是否确定退出?","message",MB_YESNO))
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
} 客户端代码:
#include < WinSock2.h>
#pragma comment( lib, "ws2_32" )
#include < stdio.h>
int main()
{
system("chcp 936>NUL");
printf( "1号客户端程序\n" );
//-----------①加载----------------
WSADATA wsaData;
WORD wVersionRequested= MAKEWORD( 2 ,2 );
if ( WSAStartup( wVersionRequested,& wsaData)!= 0 )
{
printf( "WSAStartup Failed,Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else
printf( "①加载成功\n" );
//-------------②创建流式套接字-----------------
SOCKET c1= socket( AF_INET, SOCK_STREAM, 0 );
if ( c1== INVALID_SOCKET)
{
printf( "socket() Failed,Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else
printf( "②已创建连接套接字:【%d】\n" , c1);
//------------③连接请求---------------
struct sockaddr_in Sadd;
Sadd.sin_family= AF_INET;
Sadd.sin_port= htons( 4567 );
Sadd.sin_addr.s_addr= inet_addr( "127.0.0.1" ); if ( connect( c1,( sockaddr*)& Sadd, sizeof ( Sadd))==- 1 )
{
printf( "Failed connect(),Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else //*********连接成功,可以开始发送、接收************
{
printf( "③连接成功,服务器IP地址:【%s】,端口号:【%d】\n" , inet_ntoa( Sadd.sin_addr), ntohs( Sadd.sin_port));
int a;
printf( "希望发送数据吗?(键入“1”发送,键入其他值则退出)" );
scanf( "%d" ,& a);
while ( a== 1 )
{
//---发送-----
char S_buf[]= "Hello!I am a client 1" ;
int isend= send( c1, S_buf, strlen( S_buf), 0 );
if ( isend== SOCKET_ERROR)
{
printf( "Failed send(),Error=【%d】,或者服务器意外关闭\n" , WSAGetLastError());
return 1 ;
}
else if ( isend!= 0 )
printf( "信息【%s】已发送\n" , S_buf);
else
printf( "信息无法发送给客户端\n" );
//---接收----
char R_buf[ 256 ];
int RRecv;
memset( R_buf, 0 ,sizeof ( R_buf));
RRecv= recv( c1, R_buf, 256 ,0 );
if ( RRecv== SOCKET_ERROR)
{
printf( "Failed recv(),Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else if ( RRecv== 0 )
printf( "无法收到来自服务器的任何数据,或者服务器意外关闭\n" );
else
{
printf( "接收到来自服务器的数据:【%s】\n" , R_buf);
printf( "希望继续发送数据吗?(键入”1“继续发送,键入其他值则退出)" );
scanf( "%d" ,& a);
if ( a!= 1 )
break ;
}
} //-------end 结束
printf( "已选择退出连接\n" );
} //------end 结束
//-------------------④关闭、释放------------
closesocket( c1);
WSACleanup();
printf( "④与服务器连接完毕\n" );
return 0 ;
}代码是网上一段例程自己改的。说说我的问题吧,问题就出在消息的响应上,这个自定义的WM_SOCKET似乎不能响应网络事件,但是奇怪的是,客户端可以连接成功,这似乎又说明服务端可以响应FD_ACCEPT事件,但是,服务端却毫无反应,收发信息完全无反应,即使设置了很多MessageBox打印点也没用,一个都运行不到,但是如果自己用SendMessage在服务端来手动发送消息却没问题。程序应该没语法和逻辑问题,是用win32 api写的,所以应该不是MFC消息映射之类的问题。我开发环境是VS2010+WIN7,那么,有没有可能是网络问题?各位如果有空可以帮我试一下,如果在其他机器上好用,那可能是我机器本身网络环境有问题了。
#define WM_SOCKET WM_USER+101
#include <WINSOCK2.H>
/*#include <windows.h>*/
#pragma comment(lib,"WS2_32")
//----------------窗口过程函数的声明-------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//----------------WinMain()函数------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
WNDCLASS wc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WindowProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_EXCLAMATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName="Test";
//---注册窗口类----
RegisterClass(&wc);
//---创建窗口----
HWND hwnd=CreateWindow("Test","窗口标题",WS_SYSMENU,300,0,600,400,NULL,NULL,hInstance,NULL);
if (hwnd==NULL)
{
MessageBox(hwnd,"创建窗口出错","标题栏提升",MB_OK);
return 1;
}
//---显示窗口----
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//---socket-----
WSADATA wsaData;
WORD wVersionRequested=MAKEWORD(2,2);
if (WSAStartup(wVersionRequested,&wsaData)!=0)
{
MessageBox(NULL,"WSAStartup() Failed","调用失败",0);
return 1;
}
SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (s==INVALID_SOCKET)
{
MessageBox(NULL,"socket() Failed","调用失败",0);
return 1;
}
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(4567);
sin.sin_addr.S_un.S_addr=INADDR_ANY;
if (bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
{
MessageBox(NULL,"bind() Failed","调用失败",0);
return 1;
}
if (listen(s,3)==SOCKET_ERROR)
{
MessageBox(NULL,"listen() Failed","调用失败",0);
return 1;
}
else
MessageBox(hwnd,"进入监听状态!","标题栏提示",MB_OK);
if(WSAAsyncSelect(s,hwnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE) == SOCKET_ERROR)
{
MessageBox(hwnd,"Can not register message", "" ,MB_OK);
return 0;
}
//---消息循环----
// SendMessage(hwnd , WM_SOCKET , 0 , 0);
MSG msg;
while (GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
closesocket(s);
WSACleanup();
return msg.wParam;
}
//-------------------窗口过程----------------------
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SOCKET:
{
SOCKET ss=wParam; //wParam参数标志了网络事件发生的套接口
if (WSAGETSELECTERROR(lParam))
{
closesocket(ss);
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: //-----①连接请求到来
{
sockaddr_in Cadd;
int Cadd_len=sizeof(Cadd);
SOCKET sNew=accept(ss,(sockaddr*)&Cadd,&Cadd_len);
if (ss==INVALID_SOCKET)
MessageBox(hwnd,"调用accept()失败!","标题栏提示",MB_OK);
WSAAsyncSelect(sNew,hwnd,WM_SOCKET,FD_READ|FD_CLOSE);
}break;
case FD_READ: //-----②数据发送来
{
MessageBox(hwnd,"调用accept()失败!","标题栏提示",MB_OK);
char cbuf[256];
memset(cbuf,0,256);
int cRecv=recv(ss,cbuf,256,0);
if ((cRecv==SOCKET_ERROR&& WSAGetLastError() == WSAECONNRESET)|| cRecv==0)
{
MessageBox(hwnd,"调用recv()失败!","标题栏提示",MB_OK);
closesocket(ss);
}
else if (cRecv>0)
{
MessageBox(hwnd,cbuf,"收到的信息",MB_OK);
char Sbuf[]="Hello client!I am server";
int isend=send(ss,Sbuf,sizeof(Sbuf),0);
if (isend==SOCKET_ERROR || isend<=0)
{
MessageBox(hwnd,"发送消息失败!","标题栏提示",MB_OK);
}
else
MessageBox(hwnd,"已经发信息到客户端!","标题栏提示",MB_OK);
}
}break;
case FD_CLOSE: //----③关闭连接
{
closesocket(ss);
}
break;
default:
MessageBox(hwnd,"default!","标题栏提示",MB_OK);
}
}
break;
case WM_CLOSE:
if (IDYES==MessageBox(hwnd,"是否确定退出?","message",MB_YESNO))
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
} 客户端代码:
#include < WinSock2.h>
#pragma comment( lib, "ws2_32" )
#include < stdio.h>
int main()
{
system("chcp 936>NUL");
printf( "1号客户端程序\n" );
//-----------①加载----------------
WSADATA wsaData;
WORD wVersionRequested= MAKEWORD( 2 ,2 );
if ( WSAStartup( wVersionRequested,& wsaData)!= 0 )
{
printf( "WSAStartup Failed,Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else
printf( "①加载成功\n" );
//-------------②创建流式套接字-----------------
SOCKET c1= socket( AF_INET, SOCK_STREAM, 0 );
if ( c1== INVALID_SOCKET)
{
printf( "socket() Failed,Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else
printf( "②已创建连接套接字:【%d】\n" , c1);
//------------③连接请求---------------
struct sockaddr_in Sadd;
Sadd.sin_family= AF_INET;
Sadd.sin_port= htons( 4567 );
Sadd.sin_addr.s_addr= inet_addr( "127.0.0.1" ); if ( connect( c1,( sockaddr*)& Sadd, sizeof ( Sadd))==- 1 )
{
printf( "Failed connect(),Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else //*********连接成功,可以开始发送、接收************
{
printf( "③连接成功,服务器IP地址:【%s】,端口号:【%d】\n" , inet_ntoa( Sadd.sin_addr), ntohs( Sadd.sin_port));
int a;
printf( "希望发送数据吗?(键入“1”发送,键入其他值则退出)" );
scanf( "%d" ,& a);
while ( a== 1 )
{
//---发送-----
char S_buf[]= "Hello!I am a client 1" ;
int isend= send( c1, S_buf, strlen( S_buf), 0 );
if ( isend== SOCKET_ERROR)
{
printf( "Failed send(),Error=【%d】,或者服务器意外关闭\n" , WSAGetLastError());
return 1 ;
}
else if ( isend!= 0 )
printf( "信息【%s】已发送\n" , S_buf);
else
printf( "信息无法发送给客户端\n" );
//---接收----
char R_buf[ 256 ];
int RRecv;
memset( R_buf, 0 ,sizeof ( R_buf));
RRecv= recv( c1, R_buf, 256 ,0 );
if ( RRecv== SOCKET_ERROR)
{
printf( "Failed recv(),Error=【%d】\n" , WSAGetLastError());
return 1 ;
}
else if ( RRecv== 0 )
printf( "无法收到来自服务器的任何数据,或者服务器意外关闭\n" );
else
{
printf( "接收到来自服务器的数据:【%s】\n" , R_buf);
printf( "希望继续发送数据吗?(键入”1“继续发送,键入其他值则退出)" );
scanf( "%d" ,& a);
if ( a!= 1 )
break ;
}
} //-------end 结束
printf( "已选择退出连接\n" );
} //------end 结束
//-------------------④关闭、释放------------
closesocket( c1);
WSACleanup();
printf( "④与服务器连接完毕\n" );
return 0 ;
}代码是网上一段例程自己改的。说说我的问题吧,问题就出在消息的响应上,这个自定义的WM_SOCKET似乎不能响应网络事件,但是奇怪的是,客户端可以连接成功,这似乎又说明服务端可以响应FD_ACCEPT事件,但是,服务端却毫无反应,收发信息完全无反应,即使设置了很多MessageBox打印点也没用,一个都运行不到,但是如果自己用SendMessage在服务端来手动发送消息却没问题。程序应该没语法和逻辑问题,是用win32 api写的,所以应该不是MFC消息映射之类的问题。我开发环境是VS2010+WIN7,那么,有没有可能是网络问题?各位如果有空可以帮我试一下,如果在其他机器上好用,那可能是我机器本身网络环境有问题了。
解决方案 »
- ONCTLCOLOR实现对话框透明后拖动时背景不刷新
- C++拷贝构造与对象复制
- ACCess数据库moveFirst,MoveLast的问题
- WM_CHAR发送汉字问题
- 我这有一段删除文件夹的代码,在我用时,能删除文件夹里的文件,但删除文件夹本身时却不对,说是另一个进程正在使用这个文件?
- 请教关于CSocket接受数据的问题,如果发送的数据有100K,,那么接受端的程序应该怎么写??
- com+规范与com规范有什么不同?哪有com+规范可以下载?
- 在VC中怎么使程序停留一段时间在运行??
- 对话框上能添加的控件数量是有限制的吗?
- 今天想问几个关于VC中位图操作的问题
- win7下提示"这个程序没有正确安装"
- mfc程序中如何使用 vld内存泄露检测工具?
我socket也刚接触不久,肯定很多地方都不理解,所以才要练习啊,您能告诉我具体错在哪些地方了吗?我好改。