void CPayClientDlg::HanlderSock(WPARAM wParam,LPARAM lParam)
{
switch(lParam)
{
case FD_ACCEPT:
{
SOCKADDR_IN addrIn;
int len = sizeof(SOCKADDR_IN);
SOCKET clientSock = accept(m_socket,(LPSOCKADDR)&addrIn,&len);
WSAAsyncSelect(clientSock,m_hWnd,UM_SOCK,FD_CLOSE|FD_READ);
SetDlgItemText(IDC_EDIT_LOGINFO,"accept event");
}
break;
case FD_READ:
{
WSABUF wsaBuf;
wsaBuf.buf=new char[200];
wsaBuf.len=200;

DWORD recvLen=0l; WSARecv(wParam,&wsaBuf,1,&recvLen,0,NULL,NULL); SetDlgItemText(IDC_EDIT_LOGINFO,wsaBuf.buf);
}
break;
case FD_CLOSE:
closesocket(SOCKET(wParam));
}
}
上面是消息处理函数但是接收到的数据是:
屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯葺葺'然后我就改呗
将 case FD_READ:
{
WSABUF wsaBuf;
wsaBuf.buf=new char[200];
wsaBuf.len=200;

DWORD recvLen=0l; WSARecv(wParam,&wsaBuf,1,&recvLen,0,NULL,NULL); SetDlgItemText(IDC_EDIT_LOGINFO,wsaBuf.buf);
}
break;
改成了
case FD_READ:
{
char buf[200]; int recvLen=recv(wParam,buf,200,0); buf[recvLen]=0; SetDlgItemText(IDC_EDIT_LOGINFO,buf);
}
break;
接收到了正确的数据:aaaaaaaaaaaa请问这是为什么呢??还有,如果发送端发送的数据可能超过200的长度,我是不是应该设置一个最大容量的缓冲区来读取??谢谢。。

解决方案 »

  1.   

    老兄,建议你遇到问题多查查MSDN。MSDN是最好的帮好
      

  2.   

    1.Data arrives on socket s; Windows Sockets 2 posts WSAAsyncSelect message 
    2.Application processes some other message 
    3.While processing, application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read 
    4.Application issues a recv(s,...) to read the data 
    5.Application loops to process next message, eventually reaching the WSAAsyncSelect message indicating that data is ready to read 
    6.Application issues recv(s,...), which fails with the error WSAEWOULDBLOCK. 
      

  3.   

    你是在Debug模式下跑的程序吧。
    在该模式, 如果没有给缓冲区清零,VC编译器会自动填充缓冲区,就是你看到的“屯屯屯屯……”。
    Release版本下则没有这种情况。buf[recvLen]=0; // recvLen是真实接收到的数据长度数据长度超过200,那就循环来接收,直到你真实接收到的数据长度等于你已经发送的数据长度
      

  4.   

    WSARecv是异步调教请求的吧??
      

  5.   

    WSARecv()是异步,recv()在默认情况下是同步
      

  6.   

    char buf[200] = {NULL}//给你的数组设置个初值比较好原因3#已经说了...
      

  7.   

     WSARecv(wParam,&wsaBuf,1,&recvLen,0,NULL,NULL);
    注意这句话,你只收一个字节,这能怪谁啊~
      

  8.   


    那个参数是指定WSABUF的数量吧?
      

  9.   

    请问这是为什么呢??还有,如果发送端发送的数据可能超过200的长度,我是不是应该设置一个最大容量的缓冲区来读取??谢谢。。
    -----------------------------------
    循环接收,
    int nBytes = 200;
    char buf[200] = {0};
    int nLeft = 0;
    int nCount = 0;
    while(nBytes > 0)
    {
     nCount = recv(SOCKET, &buf[nLeft], 200, 0);
     if(SOCKET_ERROR != nCount)
     {
       nBytes -= nCount;
       nLeft += nCount;
     }
     else
     {
      // Error;
     }
    }
      

  10.   

    另外你的消息处理函数里写的有些问题
    #define WSAGETSELECTERROR(lParam)       HIWORD(lParam)
    #define WSAGETSELECTEVENT(lParam)       LOWORD(lParam)
    先要判断用宏WSAGETSELECTERROR(lParam)来判断是否出错,然后使用WSAGESELECTEVENT来判断是什么事件,是FD_READ还是FD_WRITE或者是其他
      

  11.   


    谢谢指教,我还有个问题。当本地的SOCKET bind后,运行了WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_ACCEPT)有客户端连接过来,会触发FD_ACCEPT事件,根据我自定义的UM_SOCK消息来调用处理方法处理方法如下:
    void CPayClientDlg::HanlderSock(WPARAM wParam,LPARAM lParam)
    {
    if(WSAGETSELECTERROR) return;
    switch(WSAGETSELECTEVENT(lParam))
    {
    case FD_ACCEPT:
    {
    SOCKADDR_IN addrIn;
    int len = sizeof(SOCKADDR_IN);
    SOCKET clientSock = accept(m_socket,(LPSOCKADDR)&addrIn,&len);
    WSAAsyncSelect(clientSock,m_hWnd,UM_SOCK,FD_CLOSE|FD_READ);
    }
    break;
    case FD_READ:
    {
    HANDLE payThread = CreateThread(NULL,0,PayProc,&wParam,0,NULL);//这里的wParam应该是客户端连接过来的SOCKET吧,传给线程函数读不出数据来。
    CloseHandle(payThread);
    /* char buf[MAX_BUF];
    int recvLen=0;
    recvLen=recv(wParam,buf,MAX_BUF,0);//本来是想
    buf[recvLen]=0;
    AfxMessageBox(buf);改成这样代码能读出来*/
    }
    break;
    case FD_CLOSE:
    closesocket((SOCKET)wParam);
    }
    }
    线程处理函数:DWORD WINAPI CPayClientDlg::PayProc(LPVOID lpParameter)
    {
    SOCKET client_socket = *(SOCKET*)lpParameter;
    if(client_socket) {
    char buf[MAX_BUF];
    int recvLen=0;
    recvLen=recv(client_socket,buf,MAX_BUF,0);
    buf[recvLen]=0;
    AfxMessageBox(buf);
    }
    return 0;
    }是不是因为wParam超出了有效范围了?那如果我要把SOCKET传给线程去处理,怎么办呢?给客户端的SOCKET绑定FD_WRITE事件不知道怎么用,我不调用send方法也不会触发FD_WRITE事件,我调用send方法的时候都写出去了,还触发这个事件有啥用呢。。麻烦再帮我解答一次,谢谢
      

  12.   

    if(WSAGETSELECTERROR) return;
    -->
    if(WSAGETSELECTERROR(lParam))
      return;
      

  13.   

    FD_WRITE在两种情况下被触发 
    1.如果socket跟远程目标连接上后(connect()或connectEx()等),就会触发到FD_WRITE(如果socket在调用connect()等API前就将FD_WRITE用WSAAsyncSelect()设置了的话) 
    2.当socket有数据要发送,而且系统缓冲有空闲位置让你发数据(一般情况下是发送数据send,WSSend,但WSAGetLastError()返回WSAEWOULDBLOCK错误,说明系统缓冲已满,当系统缓冲有位置可发送数据后,就会触发FD_WRITE) 
      

  14.   


    晕,忘记写参数了,呵呵,不好意思帮我解决一下那个SOCKET传到线程里面去处理的问题吧,谢谢咯。