1.先建立dialog窗口,这里我就不说了,如下图:
2.直接分析上代码
- 添加Socket成员变量:
private:
SOCKET m_socket; - 初始化socket 创建socket接口
public:
bool InitSocket(void);
3.定义结构体 //为了在线程中使用socket和传递窗口,所以得定义结构体
struct RECVPARAM
{
SOCKET sock;
HWND hwnd;
};
函数coding如下:
bool Cchat_dialogDlg::InitSocket(void)
{
m_socket=socket(AF_INET,SOCK_DGRAM,0); //初始化socket 创建socket接口
if(INVALID_SOCKET==m_socket)
{
MessageBox(_T("create failure"));
return FALSE;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //inaddr_any 本地的IP
addrSock.sin_family=AF_INET;
addrSock.sin_port=htons(6000);
int retval;
retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)); //绑定本地ip
if (SOCKET_ERROR==retval)
{
closesocket(m_socket);
MessageBox(_T("bind failure"));
return FALSE;
}
return TRUE;
}
- 初始化::OnInitDialog()
xxxxxxDlg::OnInitDialog()
{
..... .....
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
InitSocket();
RECVPARAM *pRecvParam=new RECVPARAM;
pRecvParam->sock=m_socket;
pRecvParam->hwnd=m_hWnd; //所有与窗口有关的类都有一个数据成员:m_hwnd 它保存了与该类相关的窗口的句柄
HANDLE hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread); //强制转换 _In_opt_ __drv_aliasesMem LPVOID lpParameter
//在线程中创建指针 结构体的指针 存入的数据就会很多 内容更方便 附带的内容更多
}
然后定义函数RecvProc
DWORD WINAPI Cchat_dialogDlg::RecvProc(LPVOID lpParameter)
{
//获取主线程传递的套接字和窗口句柄
SOCKET sock=((RECVPARAM*)lpParameter)->sock;
HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
delete lpParameter;
SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);
CHAR recvBuf[200];
char tempBuf[300];
int retval;
while (true)
{
retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR==retval)
break;
sprintf(tempBuf,"%s 说: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
}
return 0;
}
- 编写消息映射
afx_msg LRESULT OnRecvData(WPARAM wParam,LPARAM lParam); //编写该消息的原型 注意返回类型 !!!!
ON_MESSAGE(WM_RECVDATA,OnRecvData)
LRESULT Cchat_dialogDlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
CString str=(_TCHAR*)lParam;
CString strTemp;
GetDlgItemText(IDC_EDIT_RECV,strTemp);
str+="\r\n";
str+=strTemp;
// AfxMessageBox(str);
SetDlgItemText(IDC_EDIT_RECV,str);
return 0;
}
- 按钮触发事件
void Cchat_dialogDlg::OnBnClickedBtnSend()
{
// TODO: 在此添加控件通知处理程序代码
DWORD dwip;
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwip);
SOCKADDR_IN addrTo;
addrTo.sin_addr.S_un.S_addr=htonl(dwip);
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6000);
CString strSend;
GetDlgItemText(IDC_EDIT_SEND,strSend);
// sendto(m_socket,(const char*)pstr,strlen(pstr)+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
sendto(m_socket,strSend,strlen(strSend)+1,0,(SOCKADDR*)&addrTo,sizeof(SOCKADDR));
SetDlgItemText(IDC_EDIT_SEND,_T(""));
}
运行效果:
实践是检验真知的唯一标准!