这个聊天工具的编写思路大概是这样:使用非阻塞的套接字,在初始化套接字时,使用 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的参数?或者,我这个想法完全就是错的,根本错误的理解了这个函数。
{
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的参数?或者,我这个想法完全就是错的,根本错误的理解了这个函数。
------------
简单的说就是你注册了FD_READ事件,如果有数据到达,你就会收到一个UM_SOCK消息,然后你就可以调用阻塞函数recv,将数据从系统缓冲区copy到用户缓冲区。
{
// 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);}这是我以前写的