一个很简单的练习程序,调试了一天,就是不知道到底错在哪。程序是测试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,那么,有没有可能是网络问题?各位如果有空可以帮我试一下,如果在其他机器上好用,那可能是我机器本身网络环境有问题了。

解决方案 »

  1.   

    LZ应该先弄明白WSAAsyncSelect的原理你的用法完全是错的
      

  2.   

    我试着用您说的改了下,还是老样子啊。
    我socket也刚接触不久,肯定很多地方都不理解,所以才要练习啊,您能告诉我具体错在哪些地方了吗?我好改。
      

  3.   

    wsasynselect用很简单.搜网上的socket io 5模型. 有例子代码.能跑起.
      

  4.   

    同志们,我知道哪的问题了,是win7防火墙的问题我后来在red hat下跑程序一点问题都没有,但是一到win7下面就挂了。。估计是什么安全策略导致的。。