您的位置:首页 > 编程语言 > C语言/C++

多线程聊天室的实现 C++

2012-02-15 22:03 323 查看
使用MFC进行网络编程,实现多线程聊天室

1.MFC网络编程要包含库文件 #include <afxsock.h> ,可以在stdafx.h中包含此文件

2.MFC套接字的初始化可以用AfxSocketInit()这个函数来实现。这个函数可以写在APP类中的initInstance这个函数中。

以下是主要代码实现部分

1.首先编写初始化套接字的函数

////////////////////////////////////////////////////////////////////

//名称:initStocket//

//功能:初始化套接字//

///////////////////////////////////////////////////////////////////

BOOL CUdpChatDlg::initSocket()

{

m_socket=socket(AF_INET,SOCK_DGRAM,0);

if(INVALID_SOCKET==m_socket)

{

MessageBox("套接字创建失败");

return FALSE;

}

SOCKADDR_IN addrSock;

addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSock.sin_family=AF_INET;

addrSock.sin_port=htons(6000);

int retVal;

retVal=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));

if(SOCKET_ERROR==retVal)

{

closesocket(m_socket);

MessageBox(_T("套接字绑定失败"));

return FALSE;

}

return TRUE;

}

这个初始化工作在上一篇文章中具体介绍过,在此不再赘述。

2.在Dlg类中的OnInitDialog类中调用初始化函数,并创建多线程。在OnInitDialog的return TRUE之前加上如下代码

initSocket();

RECVPARAM *pRecvParam=new RECVPARAM;

pRecvParam->hwnd=m_hWnd;

pRecvParam->sock=m_socket;

HANDLE hThread=CreateThread(NULL,0,recvFun,(LPVOID)pRecvParam,0,NULL);//创建多线程

CloseHandle(hThread);

3.创建多线程时的线程函数是recvFun,所以现在应该实现这个函数,具体的代码如下,格式不会写的看前两篇文章,或者自己查阅MSDN的CreateThread也是可以的,具体代码如下

/////////////////////////////////////////////////////////////////////////

//名称:recvFun//

//功能:线程函数,接收聊天信息并将信息处理//

////////////////////////////////////////////////////////////////////////

DWORD WINAPI CUdpChatDlg::recvFun( LPVOID lpParameter)

{

SOCKET sock=((RECVPARAM*)lpParameter)->sock;

HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;//获取套接字与窗口句柄

SOCKADDR_IN addrFrom;

int len=sizeof(SOCKADDR);

char recvBuf[200];

char tempBuf[300];

int retVal;

while(1)

{

retVal=recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);//接收聊天信息

if(SOCKET_ERROR==retVal)//如果信息接收失败,打印错误信息并退出循环

break;

sprintf(tempBuf,"%s says :%s",inet_ntoa(addrFrom.sin_addr),recvBuf);//对接收到的数据进行格式化

//AfxMessageBox(tempBuf);

::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);

/*//////////这里讲解的是如何编写消息响应函数,会写的就直接跳过这些注释

通过传递消息将得到聊天信息传送给对话框控件。消息响应函数的书写需要5步,1.::PostMessage();调用消息传递函数

2.在头文件中定义消息的值,为了避免与以有的消息值重复,可以将消息的值定为 #define WM_RECVDATA WM_USER+1 WM_USER是用户自定义的消息,然后+1避免重复

3.做消息响应函数原型的声明 afx_msg RESULT OnRecvData(WPARAM wParam,LPARAM lParam)

第二步和第三步都是在头文件中做的

4.在CPP文件中做消息映射 ON_MESSAGE(WM_RECVDATA,OnRecvData)最后不要加标点

5.最后是消息响应函数的实现

*/

}

return 0;

}

4.消息响应函数

/////////////////////////////////////////////////////////////////////////

//名称:OnRecvData//

//功能:消息响应函数,将聊天信息显示在编辑框里//

////////////////////////////////////////////////////////////////////////

LRESULT CUdpChatDlg::OnRecvData(WPARAM wParam,LPARAM lParam)

{

CString str=(char*)lParam;

CString strTemp;

GetDlgItemText(IDC_EDIT_MESSAGE,strTemp);

str+="\r\n";

str+=strTemp;

SetDlgItemText(IDC_EDIT_MESSAGE,str);

return TRUE;

}

6.实现发送按钮的功能

/////////////////////////////////////////////////////////////////

//名称:OnBnClickBtnSend()//

//功能:获取IP地址,并发送消息//

////////////////////////////////////////////////////////////////

void CUdpChatDlg::OnBnClickedBtnSend()

{

DWORD dw;

((CIPAddressCtrl*)GetDlgItem(IDC_IP_SEND))->GetAddress(dw);

SOCKADDR_IN addrTo;

addrTo.sin_addr.S_un.S_addr=htonl(dw);

addrTo.sin_family=AF_INET;

addrTo.sin_port=htons(6000);

CString strSend;

GetDlgItemText(IDC_EDIT_SEND,strSend);

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

SetDlgItemText(IDC_EDIT_SEND,"");

}

最后的运行结果如下图所示。步骤可能不是太详细,时间关系,请见谅

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: