C++套接字编程(聊天程序)

来源:互联网 发布:edius软件 编辑:程序博客网 时间:2024/06/08 03:20

创建一个基于对话框的MFC程序MultiThread,首先设置界面,并设置控件ID

接收数据是组合框,下面编辑框

发送数据是组合框,下面有IP地址框,编辑框,发送按钮,ID号如下

#define IDC_EDIT_RECV                   1000
#define IDC_IPADDRESS1                  1001
#define IDC_EDIT_SEND                   1002
#define IDC_BTN_SEND                    1003


1、首先加载套接字库,在InitStance()中调用AfxSocketInit(),在stdafx.h中加入“Afxsock.h”,AfxsocketInit()的调用一定在创建窗口之前,否者出现加载套接字失败的情况。

if (!AfxSocketInit()){AfxMessageBox(_T("加载套接字失败"));return false;}

2、在MFCmultithread.h中创建一个结构体,包含套接字和窗口的句柄,主要是投送消息时可以将两个消息同时传送。

struct RECVPARAM{SOCKET socket;HWND hWnd;};

3、在MFCmultithread类中增加成员变量m_socket和成员方法InitSocket(),InitSocket()完成m_socket的初始化和绑定。

bool CMFCmultithreadDlg::InitSocket(){m_socket = socket(AF_INET, SOCK_DGRAM, 0);if (INVALID_SOCKET == m_socket){AfxMessageBox(_T("套接字创建失败"));return false;}SOCKADDR_IN addrSock;addrSock.sin_family = AF_INET;addrSock.sin_port = htons(6000);addrSock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);int retval;retval = bind(m_socket, (SOCKADDR*)&addrSock, sizeof(SOCKADDR));if (SOCKET_ERROR == retval){closesocket(m_socket);AfxMessageBox(_T("绑定失败!"));return false;}return true;}

4、创建一个线程函数,要么是全局的,要么是静态的,或者是类的成员方法,在这里创建为类的静态方法,它不属于具体的某一个类成员,属于类。

在MFCmultithread.h中添加静态的成员方法

static DWORD WINAPI RecvProc(LPVOID lpParameter);

DWORD WINAPI  CMFCmultithreadDlg::RecvProc(LPVOID lpParameter){SOCKET socket = ((RECVPARAM*)lpParameter)->socket;HWND hWnd = ((RECVPARAM*)lpParameter)->hWnd;//窗口句柄SOCKADDR_IN addrRecv;int len = sizeof(SOCKADDR);char recvBuf[100];char tempBuf[100];int recvRst;CString recvStr;while (TRUE){//接收数据recvRst = recvfrom(socket, recvBuf, 100, 0, (SOCKADDR*)&addrRecv, &len);if (SOCKET_ERROR == recvRst){break;}sprintf(tempBuf, "%s 说:%s\r\n", inet_ntoa(addrRecv.sin_addr), recvBuf);// //recvStr += tempBuf;//这种方式更加简单不用使用消息// //::SetDlgItemText(hWnd, IDC_EDIT_RECV, recvStr);//使用自定义消息的方式来对控件填充内容::PostMessage(hWnd, WM_RECVDATA, 0, (LPARAM)tempBuf);}return 0;}

5、在OnInitDialog中调用InitSocket完成套接字初始化

InitSocket();RECVPARAM *pRecvParm = new RECVPARAM();pRecvParm->socket = m_socket;pRecvParm->hWnd = m_hWnd;HANDLE hThreadRecv = CreateThread(NULL, 0, RecvProc, (LPVOID)pRecvParm, 0, NULL);CloseHandle(hThreadRecv);
6、添加一个自定义消息响应函数

#define WM_RECVDATA WM_USER+1 

afx_msg LRESULT OnRecvData(WPARAM wParam,LPARAM lParam);

ON_MESSAGE(WM_RECVDATA, OnRecvData)

在类中添加OnRecvData函数

LRESULT CMFCmultithreadDlg::OnRecvData(WPARAM wParam, LPARAM lParam){CString str((char*)lParam);CString strTemp;GetDlgItemText(IDC_EDIT_RECV, strTemp);str += "\r\n";str += strTemp;SetDlgItemText(IDC_EDIT_RECV, str);return true;}
7、添加发送按钮的响应函数

void CMFCmultithreadDlg::OnBtnSend(){// TODO:  在此添加控件通知处理程序代码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));SetDlgItemText(IDC_EDIT_SEND, "");}




0 0
原创粉丝点击