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

创建一个基于对话框的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, "");
}




  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

feng_blog6688

只需一个赞,谢谢你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值