这个聊天工具的编写思路大概是这样:使用非阻塞的套接字,在初始化套接字时,使用 if(SOCKET_ERROR  == WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))
{
MessageBox("注册网络读取事件失败!");
return FALSE;
}
将UM_SOCK与读事件绑定起来,在消息响应函数中显示接收的消息。
我想做的事情,是如何能够在发送消息时,将发送的消息也显示出来。我有一个笨办法可以使用:
发送消息时,再发送一条自定义消息,消息的参数是要发送的字符串,然后在消息响应函数中,先获取原来的内容,再加上发送的内容,一起SetDlgItemText上去。我的问题是,有没有其他的方法,最好是利用了WSAAsyncSelect。
说白了,就是我不会用这个函数,具体的说,是两个问题:
1.MSDN上说:Issuing a WSAAsyncSelect for a socket cancels any previous WSAAsyncSelect or WSAEventSelect for the same socket. For example, to receive notification for both reading and writing, the application must call WSAAsyncSelect with both FD_READ and FD_WRITE, as follows:rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);那我是不是应该在初始化的时候就改成这样呢?然后在消息响应函数中,switch case一下看是哪个消息。
2.如何设置将要发送的数据传递给UM_SOCK的参数?或者,我这个想法完全就是错的,根本错误的理解了这个函数。

解决方案 »

  1.   

    if(SOCKET_ERROR  == WSAAsyncSelect(m_socket,m_hWnd,UM_SOCK,FD_READ))
    ------------
    简单的说就是你注册了FD_READ事件,如果有数据到达,你就会收到一个UM_SOCK消息,然后你就可以调用阻塞函数recv,将数据从系统缓冲区copy到用户缓冲区。
      

  2.   

    将发送的消息显示出来直接再send完之后用SetDlgItemText()函数就可以了啊void CChatDlg::OnBtnSend() 
    {
    // TODO: Add your control notification handler code here
    DWORD  dwIP;
    ((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);

    SOCKADDR_IN  addrto;
    addrto.sin_family=AF_INET;
    addrto.sin_port=htons(6000);
    addrto.sin_addr.S_un.S_addr=htonl(dwIP);

    CString  strSend;
    GetDlgItemText(IDC_EDIT_SEND,strSend);

    sendto(m_socket,strSend,strSend.GetLength()+1,0,(SOCKADDR*)&addrto,sizeof(SOCKADDR));

    /*
    CString  st;
    GetDlgItemText(IDC_EDIT_RECV,st);
    strSend+="\r\n";
    st+="你说 : ";
    st+=strSend;
    SetDlgItemText(IDC_EDIT_RECV,st);
    SetDlgItemText(IDC_EDIT_SEND,"");
    */
    //获取本机名
    char  name[255];
    HOSTENT*  hostent;
    if(SOCKET_ERROR==gethostname(name,sizeof(name)))
    {
    MessageBox("获取主机名失败!");
    return;
    }
    //获取本机IP
    hostent=gethostbyname(name);
    CString  st;
    GetDlgItemText(IDC_EDIT_RECV,st);
    strSend+="\r\n";
    st+=inet_ntoa(*(in_addr *)hostent->h_addr_list[0]);
    st+="  说:  ";
    st+=strSend;
    SetDlgItemText(IDC_EDIT_RECV,st);
    SetDlgItemText(IDC_EDIT_SEND,"");
    //让滚动条始终处在底端
    CEdit *pedit=(CEdit*)GetDlgItem(IDC_EDIT_RECV); 
    int   nline=pedit-> GetLineCount(); 
    pedit-> LineScroll(nline-1);}这是我以前写的