下面我们来编写多线程的网络聊天程序:
环境:新建一个基于对话框的应用程序
第一步:我们来设置资源库里面的内容
第二步:加载套接字库进行版本协商,进行加载套接字库
——这个代码我们可以在我们的APP中的InitInstance进行编写
if
{
AfxMessageBox("加载套接字库失败!");
return
}//这里我们通过条件语句来判断是否已经加载套接字库了
【注意】这里请我们千万不要忘了添加我们的头文件Afxsock.h
——我们在StdAfx.h中添加即可
第三步:我们来对我们的套接字库进行初始化
BOOL
{
m_socket=socket(AF_INET,SOCK_DGRAM,0);//来创建一个套接字
if
{
MessageBox("创建套接字失败!");
return
}
SOCKADDR_IN
addrsock.sin_family=AF_INET;
addrsock.sin_port=htons(6000);
addrsock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
int
retval=bind(m_socket,(SOCKADDR*)&addrsock,sizeof(SOCKADDR));
if
{
closesocket(m_socket);
MessageBox("绑定失败!");
return
}
return
}
【注意】只有上面的代码我们的套接字的初始化工作还没有完,我们还要在我们的Dlg类中的OnInitDialog()函数中调用一下这个初始化函数InitSocket(),这样才有效。
第四步:接下来我们来创建一个结构体,让他来记录相关信息(我们放在我们的CDlg中)
struct
{
SOCKET
HWND
};
第五步:我们利用我们刚刚创建的结构体来创建线程(在我们的OnInitDialog函数中)
RECVPARAM
pRecvParam->sock=m_socket;
pRecvParam->hwnd=m_hWnd;
HANDLE
CloseHandle(hThread);
第六步:我们来创建一个线程函数
——(注意我们要将这个函数声明为全局函数或者如果你要将这个线程函数声明为Dlg的成员函数也可以,但是你必须将这个函数定义成静态的,因为静态的函数他不属于任何一个对象,他是属于这个类的)
线程函数的编写:
DWORD
{
SOCKET
HWND
delete
SOCKADDR_IN
int
char
char
int
while(TRUE)
{
retval=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR==retval)//判断接受是否成功
break;
sprintf(tempBuf,"%s说:
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);//我们接下来将我们的数据传给我们的对话框,这里利用发送消息的方式来传递
}
return
}
第七步:下面是消息响应函数的实现函数
void
{
CString
CString
GetDlgItemText(IDC_EDIT_RECV,strTemp);//获取文本
str+="\r\n";//增加一个换行
str+=strTemp;
SetDlgItemText(IDC_EDIT_RECV,str);
}
第八步:我们来设置发送端
void
{
//
DWORD
((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);
SOCKADDR_IN
addrTo.sin_family=AF_INET;
addrTo.sin_port=htons(6000);
addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
CString
GetDlgItemText(IDC_EDIT_SEND,strSend);//得到我们要发送的数据
sendto(m_socket,strSend,strSend.GetLength()+1,0,
(SOCKADDR*)&addrTo,sizeof(SOCKADDR));//发送数据
SetDlgItemText(IDC_EDIT_SEND,"");//将我们发送编辑框设置为空
}
联系客服