18 MFC TCP和UDP 网络通信

这篇具有很好参考价值的文章主要介绍了18 MFC TCP和UDP 网络通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP服务器

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib") //包含静态库

/*
.obj + .lib 文件 组合打包成 .exe
*/

int main()
{
	//1.加载套接字库
	//第一个参数:版本
	WORD wVersionRequseted=MAKEWORD(2,2);//低位字节:主版本,高位字节:次版本
	//第二个参数:
	WSADATA wd;
	if (0 != WSAStartup(wVersionRequseted, &wd))
	{
		printf("加载套接字失败!错误代号:%d\n", GetLastError());
		return 0;
	}

	//2.判断实际加载的版本
	if (LOBYTE(wd.wVersion) != 2 || HIBYTE(wd.wVersion) != 2)
	{
		printf("加载套接字版本不一致!错误代号:%d\n", GetLastError());
		return 0;
	}

	//3.创建套接字
	//第一个参数:地址簇 IPV4
	//第二个参数:套接字类型,流式套接字( SOCK_STREAM->TCP) 数据报套接字(SOCK_DGRAM->UDP)
	//第三个参数:待定协议
	SOCKET sockServer=socket(AF_INET, SOCK_STREAM, 0);


	//4.设置套接字地址簇
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;//地址簇
	addrSrv.sin_addr.S_un.S_addr =htonl(INADDR_ANY);//设置网卡 htonl:主机字节顺序转换为网络字节顺序
	addrSrv.sin_port =htons(2020);//端口号范围 0 -> 65535  0:不取 1->1024 系统服务器 , 1024以上端口自己用
	
	//SOCKADDR_IN==sockaddr_in

	//5.绑定
	if (SOCKET_ERROR == bind(sockServer, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))//绑定套接字,套接字地址簇,大小
	{
		printf("绑定失败!错误代号:%d\n", WSAGetLastError());
		return 0;
	}
	
	//6.将套接字设置为监听模式
	//第一个参数:套接字
	//第二个参数:挂起连接的队列的最大长度
	if (SOCKET_ERROR == listen(sockServer, 5))
	{
		printf("监听失败!错误代号:%d\n", WSAGetLastError());
		return 0;
	}

	//7.等待客户端连接请求
	SOCKADDR_IN addrClient;
	int length = sizeof(SOCKADDR);
	while (1)
	{
		SOCKET clientSocket=accept(sockServer, (SOCKADDR*)&addrClient, &length);
		//inet_ntoa() 是一个用于将 IPv4 地址从网络字节序转换为点分十进制字符串表示的函数
		//ntohl 网络字节顺序转换成主机字节顺序
		printf("客户端:%s:%d连接服务器\n", inet_ntoa(addrClient.sin_addr),addrClient.sin_port);

		//接收信息
		//第一个参数:套接字
		//第二个参数:发送的缓冲区
		//第三个参数:缓冲区大小
		char szRecvBuf[100] = { 0 };
		recv(clientSocket, szRecvBuf, sizeof(szRecvBuf), 0);
		printf("客户端说:%s\n", szRecvBuf);


		//发送信息
		char szSenBuf[100] = "客户端,hello";
		send(clientSocket, szSenBuf, strlen(szSenBuf) + 1, 0);


		//关闭套接字
		closesocket(clientSocket);

	}
	//8.关闭套接字
	closesocket(sockServer);

	//9.清理库
	WSACleanup();

	return 0;
}

TCP客户端

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib") //包含静态库

/*
.obj + .lib 文件 组合打包成 .exe
*/

int main()
{

	char szServerIPAddress[16];
	printf("请输入需要连接的服务器IP地址:\n");
	scanf("%s",szServerIPAddress);

	//1.加载套接字库
	//第一个参数:版本
	WORD wVersionRequseted = MAKEWORD(2, 2);//低位字节:主版本,高位字节:次版本
	//第二个参数:
	WSADATA wd;
	if (0 != WSAStartup(wVersionRequseted, &wd))
	{
		printf("加载套接字失败!错误代号:%d\n", GetLastError());
		return 0;
	}

	//2.判断实际加载的版本
	if (LOBYTE(wd.wVersion) != 2 || HIBYTE(wd.wVersion) != 2)
	{
		printf("加载套接字版本不一致!错误代号:%d\n", GetLastError());
		return 0;
	}

	//3.创建套接字
	//第一个参数:地址簇 IPV4
	//第二个参数:套接字类型,流式套接字( SOCK_STREAM->TCP) 数据报套接字(SOCK_DGRAM->UDP)
	//第三个参数:待定协议
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);


	//4.连接服务器
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;//地址簇
	addrSrv.sin_addr.S_un.S_addr = inet_addr(szServerIPAddress);
	addrSrv.sin_port = htons(2020);

	if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))
	{
		printf("连接服务器失败.错误代号:%d\n",WSAGetLastError());
		return 0;
	}
	printf("连接服务器成功!\n");
	
	//5.发送信息
	char szSendBuf[100] = "服务器,hello";
	send(sockClient, szSendBuf, strlen(szSendBuf) + 1,0);

	//接收信息
	//第一个参数:套接字
	//第二个参数:发送的缓冲区
	//第三个参数:缓冲区大小
	char szRecvBuf[100] = { 0 };
	recv(sockClient, szRecvBuf, sizeof(szRecvBuf), 0);
	printf("服务器说:%s\n", szRecvBuf);


	//7.关闭套接字
	closesocket(sockClient);

	//8.清理库
	WSACleanup();

	return 0;
}

有错误代码可以进行查找
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
将错误代码输入
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

UDP 服务器

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib") //包含静态库

/*
.obj + .lib 文件 组合打包成 .exe
*/

int main()
{

	

	//1.加载套接字库
	//第一个参数:版本
	WORD wVersionRequseted = MAKEWORD(2, 2);//低位字节:主版本,高位字节:次版本
	//第二个参数:
	WSADATA wd;
	if (0 != WSAStartup(wVersionRequseted, &wd))
	{
		printf("加载套接字失败!错误代号:%d\n", GetLastError());
		return 0;
	}

	//2.判断实际加载的版本
	if (LOBYTE(wd.wVersion) != 2 || HIBYTE(wd.wVersion) != 2)
	{
		printf("加载套接字版本不一致!错误代号:%d\n", GetLastError());
		return 0;
	}

	//3.创建套接字
	//第一个参数:地址簇 IPV4
	//第二个参数:套接字类型,流式套接字( SOCK_STREAM->TCP) 数据报套接字(SOCK_DGRAM->UDP)
	//第三个参数:待定协议
	SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, 0);


	//4.设置套接字地址簇
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;//地址簇
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//设置网卡 htonl:主机字节顺序转换为网络字节顺序
	addrSrv.sin_port = htons(2021);//端口号范围 0 -> 65535  0:不取 1->1024 系统服务器 , 1024以上端口自己用

	//SOCKADDR_IN==sockaddr_in

	//5.绑定
	if (SOCKET_ERROR == bind(sockServer, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))//绑定套接字,套接字地址簇,大小
	{
		printf("绑定失败!错误代号:%d\n", WSAGetLastError());
		return 0;
	}

	//6.接收消息
	SOCKADDR_IN addrclient;
	int length = sizeof(SOCKADDR);
	char szRecvBuf[100];
	recvfrom(sockServer, szRecvBuf, sizeof(szRecvBuf), 0,(SOCKADDR*)&addrclient,&length);
	printf("客户端:%s\n", szRecvBuf);


	//发送
	char szSendBuf[100] = "客户端你好!";
	sendto(sockServer, szSendBuf,strlen(szSendBuf)+1,0, (SOCKADDR*)&addrclient,sizeof(SOCKADDR));

	//7.关闭套接字
	closesocket(sockServer);

	//8.清理库
	WSACleanup();

	return 0;
}

UDP客户端

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib") //包含静态库

/*
.obj + .lib 文件 组合打包成 .exe
*/

int main()
{

	char szServerIPAddress[16];
	printf("请输入需要连接的服务器IP地址:\n");
	scanf("%s", szServerIPAddress);

	//1.加载套接字库
	//第一个参数:版本
	WORD wVersionRequseted = MAKEWORD(2, 2);//低位字节:主版本,高位字节:次版本
	//第二个参数:
	WSADATA wd;
	if (0 != WSAStartup(wVersionRequseted, &wd))
	{
		printf("加载套接字失败!错误代号:%d\n", GetLastError());
		return 0;
	}

	//2.判断实际加载的版本
	if (LOBYTE(wd.wVersion) != 2 || HIBYTE(wd.wVersion) != 2)
	{
		printf("加载套接字版本不一致!错误代号:%d\n", GetLastError());
		return 0;
	}

	//3.创建套接字
	//第一个参数:地址簇 IPV4
	//第二个参数:套接字类型,流式套接字( SOCK_STREAM->TCP) 数据报套接字(SOCK_DGRAM->UDP)
	//第三个参数:待定协议
	SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, 0);


	//4.发送消息
	SOCKADDR_IN addrServer;
	addrServer.sin_addr.S_un.S_addr = inet_addr(szServerIPAddress);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(2021);
	int length = sizeof(SOCKADDR);

	char szSendBuf[100]="服务器你好!";
	sendto(sockServer, szSendBuf, sizeof(szSendBuf), 0, (SOCKADDR*)&addrServer,sizeof(SOCKADDR));


	//6.接收消息
	SOCKADDR_IN addrclient;
	length = sizeof(SOCKADDR);
	char szRecvBuf[100];
	recvfrom(sockServer, szRecvBuf, sizeof(szRecvBuf), 0, (SOCKADDR*)&addrclient, &length);
	printf("服务器:%s\n", szRecvBuf);

	//7.关闭套接字
	closesocket(sockServer);

	//8.清理库
	WSACleanup();

	return 0;
}

MFC TCP通信

勾选高级功能18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

如果没有勾选
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

TCP服务器

ui 设置
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
添加套接字类
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
创建虚函数接收连接18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
在服务器里面创建客户端类18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
在客户端类中添加接收的响应函数18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
断开连接18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

// TCPChatServerDlg.h: 头文件

//

#pragma once

//类的前置声明
class ClistenSocket;

// CTCPChatServerDlg 对话框
class CTCPChatServerDlg : public CDialogEx
{
// 构造
public:
	CTCPChatServerDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_TCPCHATSERVER_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	ClistenSocket* m_plistSocket;
	afx_msg void OnBnClickedBtnStart();
	afx_msg void OnBnClickedBtnClose();
	CListCtrl m_list;
};

// TCPChatServerDlg.cpp: 实现文件

//

#include "pch.h"
#include "framework.h"
#include "TCPChatServer.h"
#include "TCPChatServerDlg.h"
#include "afxdialogex.h"
#include "ClistenSocket.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define PORT 2020 //端口号

// CTCPChatServerDlg 对话框



CTCPChatServerDlg::CTCPChatServerDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_TCPCHATSERVER_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_plistSocket = NULL;
}

void CTCPChatServerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_list);
}

BEGIN_MESSAGE_MAP(CTCPChatServerDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_START, &CTCPChatServerDlg::OnBnClickedBtnStart)
	ON_BN_CLICKED(IDC_BTN_CLOSE, &CTCPChatServerDlg::OnBnClickedBtnClose)
END_MESSAGE_MAP()


// CTCPChatServerDlg 消息处理程序

BOOL CTCPChatServerDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	m_list.InsertColumn(0,L"IP地址",LVCFMT_LEFT,150);
	m_list.InsertColumn(1, L"端口号", LVCFMT_LEFT,80);
	m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CTCPChatServerDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CTCPChatServerDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CTCPChatServerDlg::OnBnClickedBtnStart()
{
	CString strMsg;
	m_plistSocket = new ClistenSocket;
	//创建套接字
	//第一个参数:端口号
	//第二个参数:套接字类型 TCP->SOCK_STREAM ,UDP->SOCK_DGRAM
	//后前面全是默认参数
	if (FALSE==m_plistSocket->Create(PORT, SOCK_STREAM))
	{
		strMsg.Format(L"开启服务器失败.错误代号:%d",GetLastError());
		MessageBox(strMsg, L"提示");
		return;
	}

	//将套接字设置为监听模式
	if (FALSE == m_plistSocket->Listen())
	{
		strMsg.Format(L"开启服务器失败.错误代号:%d", GetLastError());
		MessageBox(strMsg, L"提示");
		return;
	}

	//禁用按钮
	GetDlgItem(IDC_BTN_START)->EnableWindow(FALSE);
	GetDlgItem(IDC_BTN_CLOSE)->EnableWindow(TRUE);

}


void CTCPChatServerDlg::OnBnClickedBtnClose()
{
	if (m_plistSocket)
	{
		m_plistSocket->Close();

		delete m_plistSocket;
		m_plistSocket = NULL;


		//禁用按钮
		GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_CLOSE)->EnableWindow(FALSE);
	}
}

//ClistenSocket.h

#pragma once
#include <afxsock.h>
class ClistenSocket :public CSocket
{
public:
	ClistenSocket();
	~ClistenSocket();
	virtual void OnAccept(int nErrorCode);
};

//ClistenSocket.cpp

#include "pch.h"
#include "ClistenSocket.h"
#include "CClientSocket.h"
#include "TCPChatServerDlg.h"
#include "TCPChatServer.h"

ClistenSocket::ClistenSocket()
{
}

ClistenSocket::~ClistenSocket()
{
}

//监听到
void ClistenSocket::OnAccept(int nErrorCode)
{
	CClientSocket *pSocket = new CClientSocket;

	//第一个参数:连接的新的套接字,其他参数为默认
	Accept(*pSocket);
	CString strIPAddress;
	UINT uPort;
	//获取IP地址
	pSocket->GetPeerName(strIPAddress, uPort);

	//保存客户端套接字指针对象
	((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.push_back(pSocket);

	//获取主对话框中的UI
	CTCPChatServerDlg* pMainDlg=(CTCPChatServerDlg*)AfxGetMainWnd();
	//插入到列表中
	int nCount = pMainDlg->m_list.GetItemCount();//获取插入行数
	pMainDlg->m_list.InsertItem(nCount, strIPAddress);
	CString str;
	str.Format(L"%d", uPort);
	pMainDlg->m_list.SetItemText(nCount,1,str);//插入端口号


	str.Format(L"客户端%s:%d上线了\r\n",strIPAddress,uPort);
	//转发给所有客户端
	//((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.push_back(pSocket);
	std::list<CClientSocket*>::iterator it;
	for (it = ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.begin(); it != ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.end(); ++it)
	{
		CClientSocket* pSocket = *it;
		//发送
		pSocket->Send(str, str.GetLength() * 2);//长度*2 ==字节数
	}


	CSocket::OnAccept(nErrorCode);
}

//CClientSocket.h

#pragma once
#include <afxsock.h>
class CClientSocket :public CSocket
{
public:
	CClientSocket();
	~CClientSocket();
	virtual void OnReceive(int nErrorCode);
	virtual void OnClose(int nErrorCode);
};

//CClientSocket.cpp

#include "pch.h"
#include "CClientSocket.h"
#include "TCPChatServer.h"
#include "TCPChatServerDlg.h"
CClientSocket::CClientSocket()
{
}

CClientSocket::~CClientSocket()
{
}


//接收
void CClientSocket::OnReceive(int nErrorCode)
{
	wchar_t szRecvBuf[512];
	ZeroMemory(szRecvBuf, sizeof(szRecvBuf));//清空内存,防止没有字符串终止符出现乱码
	//接收数据
	//第一个参数:缓存
	//第二个参数:缓存大小
	int n=Receive(szRecvBuf, sizeof(szRecvBuf));//n为实际接收多少字节
	//AfxMessageBox(szRecvBuf);

	//获取当前时间
	CTime time = CTime::GetCurrentTime();
	CString strIPAddress;
	UINT uPort;
	GetPeerName(strIPAddress,uPort);//获取IP地址和端口号
	CString str;
	str.Format(L"%s:%d\t%s\r\n%s\r\n", strIPAddress, uPort,time.Format(L"%H:%M:%S"), szRecvBuf);

	//转发给所有客户端
	//((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.push_back(pSocket);
	std::list<CClientSocket*>::iterator it;
	for (it = ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.begin(); it != ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.end(); ++it)
	{
		CClientSocket* pSocket = *it;
		//发送
		pSocket->Send(str, str.GetLength() * 2);//长度*2 ==字节数
	}


	CSocket::OnReceive(nErrorCode);
}


void CClientSocket::OnClose(int nErrorCode)
{
	CString strIPAddress;
	UINT uPort;
	GetPeerName(strIPAddress, uPort);//获取IP地址和端口号
	//删除链表中的IP地址信息
	CTCPChatServerDlg* pMainDlg = (CTCPChatServerDlg*)AfxGetMainWnd();
	int nCount = pMainDlg->m_list.GetItemCount();//获取总行数
	for (int i = 0; i < nCount; i++)
	{
		//判断IP地址和端口号是否和链表中数据一致
		if (pMainDlg->m_list.GetItemText(i, 0) == strIPAddress && _wtoi(pMainDlg->m_list.GetItemText(i, 1)) == uPort)
		{
			pMainDlg->m_list.DeleteItem(i);
			break;
		}
	}


	//从list释放内存
	std::list<CClientSocket*>::iterator it;
	for (it = ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.begin(); it != ((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.end(); ++it)
	{
		CClientSocket* pSocket = *it;
		if (pSocket == this)
		{
			((CTCPChatServerApp*)AfxGetApp())->m_Clientlist.erase(it);
			delete pSocket;
			break;
		}
	}

	CSocket::OnClose(nErrorCode);
}

18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

TCP 客户端

ui 设置
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
客户端类18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
接受响应函数18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

// TCPChatClientDlg.h: 头文件

//

#pragma once
class CClientSocket;

// CTCPChatClientDlg 对话框
class CTCPChatClientDlg : public CDialogEx
{
// 构造
public:
	CTCPChatClientDlg(CWnd* pParent = nullptr);	// 标准构造函数
	~CTCPChatClientDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_TCPCHATCLIENT_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CString m_strSendMsg;
	CClientSocket* m_pClientSocket;
	afx_msg void OnBnClickedBtnSend();
	afx_msg void OnBnClickedBtnClose();
	CEdit m_edit;
	void ShowMessage(CString strMsg);
};

// TCPChatClientDlg.cpp: 实现文件

//

#include "pch.h"
#include "framework.h"
#include "TCPChatClient.h"
#include "TCPChatClientDlg.h"
#include "afxdialogex.h"
#include "CClientSocket.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


#define PORT 2020
// CTCPChatClientDlg 对话框



CTCPChatClientDlg::CTCPChatClientDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_TCPCHATCLIENT_DIALOG, pParent)
	, m_strSendMsg(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_pClientSocket = NULL;
}

CTCPChatClientDlg::~CTCPChatClientDlg()
{
	if (m_pClientSocket)
	{
		delete m_pClientSocket;
		m_pClientSocket = NULL;
	}
}

void CTCPChatClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT2, m_strSendMsg);
	DDX_Control(pDX, IDC_EDIT1, m_edit);
}

BEGIN_MESSAGE_MAP(CTCPChatClientDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_SEND, &CTCPChatClientDlg::OnBnClickedBtnSend)
	ON_BN_CLICKED(IDC_BTN_CLOSE, &CTCPChatClientDlg::OnBnClickedBtnClose)
END_MESSAGE_MAP()


// CTCPChatClientDlg 消息处理程序

BOOL CTCPChatClientDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	CString strMsg;

	m_pClientSocket = new CClientSocket;
	if (FALSE == m_pClientSocket->Create())//默认为TCP协议
	{
		strMsg.Format(L"初始化网络失败.错误代号:%d", GetLastError());
		MessageBox(strMsg, L"提示");
		//结束对话框
		EndDialog(IDOK);
	}

	//连接服务器
	if (FALSE==m_pClientSocket->Connect(L"192.168.1.109", PORT))
	{
		strMsg.Format(L"连接服务器失败.错误代号:%d", GetLastError());
		MessageBox(strMsg, L"提示");
		//结束对话框
		EndDialog(IDOK);
	}

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CTCPChatClientDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CTCPChatClientDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


//发送
void CTCPChatClientDlg::OnBnClickedBtnSend()
{
	UpdateData(TRUE);
	if (m_strSendMsg.IsEmpty())
	{
		MessageBox(L"发消息为空");
		return;
	}
	if (m_strSendMsg.GetLength() > 512)
	{
		MessageBox(L"发送内容太多");
		return;
	}

	//发消息
	//第一个参数:发送的消息
	//第二个参数:发送的长度
	int n=m_pClientSocket->Send(m_strSendMsg,m_strSendMsg.GetLength()*2);

}


//关闭
void CTCPChatClientDlg::OnBnClickedBtnClose()
{
	EndDialog(IDOK);
}

//显示消息
void CTCPChatClientDlg::ShowMessage(CString strMsg)
{
	
	//获取原来字符的长度
	int nLength = m_edit.GetWindowTextLength();
	m_edit.SetSel(nLength, -1);//设置光标位置 
	//追加
	strMsg = strMsg + L"\r\n";
	m_edit.ReplaceSel(strMsg);//设置文本字符串
}

//CClientSocket.h

#pragma once
#include <afxsock.h>
class CClientSocket :public CSocket
{
public:
	CClientSocket();
	~CClientSocket();
	virtual void OnReceive(int nErrorCode);
};

//CClientSocket.cpp

#include "pch.h"
#include "CClientSocket.h"
#include "TCPChatClientDlg.h"
CClientSocket::CClientSocket()
{
}

CClientSocket::~CClientSocket()
{
}


void CClientSocket::OnReceive(int nErrorCode)
{
	
	wchar_t szRecvBuf[512];
	ZeroMemory(szRecvBuf, sizeof(szRecvBuf));//清空内存,防止没有字符串终止符出现乱码
	//接收数据
	//第一个参数:缓存
	//第二个参数:缓存大小
	int n = Receive(szRecvBuf, sizeof(szRecvBuf));//n为实际接收多少字节
	
	//显示到界面
	//获取到控件
	CTCPChatClientDlg* pMainDlg=(CTCPChatClientDlg*)AfxGetMainWnd();
	pMainDlg->ShowMessage(szRecvBuf);


	CSocket::OnReceive(nErrorCode);
}

18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

MFC UDP通信

ui 设置
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

添加关联变量
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp> 添加类
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp
18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp

// UDPChatDlg.h: 头文件

//

#pragma once
#include "CClientSocket.h"

// CUDPChatDlg 对话框
class CUDPChatDlg : public CDialogEx
{
// 构造
public:
	CUDPChatDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_UDPCHAT_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	CIPAddressCtrl m_IPAddressCtrl;
	int m_uPort;
	CEdit m_edit;
	CString m_strSendMsg;
	afx_msg void OnBnClickedBtnSend();
	CClientSocket m_socket;
	void ShowMessage(CString strMsg);
	int m_uMyPort;
	afx_msg void OnBnClickedBtnCreate();
};

// UDPChatDlg.cpp: 实现文件

//

#include "pch.h"
#include "framework.h"
#include "UDPChat.h"
#include "UDPChatDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif



// CUDPChatDlg 对话框



CUDPChatDlg::CUDPChatDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_UDPCHAT_DIALOG, pParent)
	, m_strSendMsg(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CUDPChatDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_IPADDRESS1, m_IPAddressCtrl);
	DDX_Text(pDX, IDC_EDIT1, m_uPort);
	DDX_Control(pDX, IDC_EDIT2, m_edit);
	DDX_Text(pDX, IDC_EDIT3, m_strSendMsg);
	DDX_Text(pDX, IDC_EDIT4, m_uMyPort);
}

BEGIN_MESSAGE_MAP(CUDPChatDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_SEND, &CUDPChatDlg::OnBnClickedBtnSend)
	ON_BN_CLICKED(IDC_BTN_CREATE, &CUDPChatDlg::OnBnClickedBtnCreate)
END_MESSAGE_MAP()


// CUDPChatDlg 消息处理程序

BOOL CUDPChatDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CUDPChatDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CUDPChatDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


//发送
void CUDPChatDlg::OnBnClickedBtnSend()
{
	UpdateData(TRUE);
	if (m_strSendMsg.IsEmpty())
	{
		MessageBox(L"不能发送空消息");
		return;
	}
	if (m_strSendMsg.GetLength() >= 512)
	{
		MessageBox(L"发送消息过长");
		return;
	}
	CString strIPAddress;
	m_IPAddressCtrl.GetWindowText(strIPAddress);
	if (strIPAddress == L"0.0.0.0")
	{
		MessageBox(L"IP地址不能为空");
		return;
	}
	m_socket.SendTo(m_strSendMsg, m_strSendMsg.GetLength() * 2, m_uPort,strIPAddress);
}


void CUDPChatDlg::ShowMessage(CString strMsg)
{
	int nLength = m_edit.GetWindowTextLength();
	m_edit.SetSel(nLength, -1);//设置光标位置

	//追加
	strMsg = strMsg + L"\r\n";
	m_edit.ReplaceSel(strMsg);
}


void CUDPChatDlg::OnBnClickedBtnCreate()
{
	UpdateData(TRUE);
	CString str;
	if (FALSE == m_socket.Create(m_uMyPort, SOCK_DGRAM))
	{
		str.Format(L"初始化网络失败,错误代号:%d", GetLastError());
		MessageBox(str, L"提示");
		EndDialog(IDOK);
		return ;
	}
}

//CClientSocket.h

#pragma once

#include <afxsock.h>
class CClientSocket :public CSocket
{
public:
	CClientSocket();
	~CClientSocket();
	virtual void OnReceive(int nErrorCode);
};

//CClientSocket.cpp

#include "pch.h"
#include "CClientSocket.h"
#include "UDPChatDlg.h"

CClientSocket::CClientSocket()
{
}

CClientSocket::~CClientSocket()
{
}


void CClientSocket::OnReceive(int nErrorCode)
{
	wchar_t szRecvMsg[512];
	ZeroMemory(szRecvMsg,sizeof(szRecvMsg));

	//接收数据
	CString strIPaddress;
	UINT uPort;
	ReceiveFrom(szRecvMsg,sizeof(szRecvMsg),strIPaddress,uPort);

	//显示到界面
	CUDPChatDlg* pMainDlg=(CUDPChatDlg*)AfxGetMainWnd();
	pMainDlg->ShowMessage(szRecvMsg);

	CSocket::OnReceive(nErrorCode);
}

18 MFC TCP和UDP 网络通信,mfc,tcp/ip,udp文章来源地址https://www.toymoban.com/news/detail-619965.html

到了这里,关于18 MFC TCP和UDP 网络通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java网络编程之IP,端口号,通信协议(UDP,TCP)

    ① C/S :客户端/服务器 在用户本地需要下载安装客户端程序,在远程有一个服务器端程序。 优点:画面精美,用户体验好 缺点:用户需要下载更新 ② B/S :浏览器/服务器 只需要一个浏览器,用户通过指定网址访问对应的服务器。 优点:不需要开发客户端,只需要页面+服务

    2024年02月03日
    浏览(84)
  • 【网络通信】探索UDP与TCP协议、IP地址和端口号的奥妙

    🌺 个人主页: Dawn黎明开始 🎀 系列专栏: 网络奇幻之旅 ⭐ 每日一句:往前走,朝着光 📢 欢迎大家:关注 🔍 +点赞 👍 +评论📝+收藏⭐️ 文章目录 📋前言 一.网络通信 1.1网络通信协议 1.2TCP/IP协议中的四个层次 二.UDP协议 2.1定义 2.2UDP连接的交互过程 三.TCP协议 3.1定义

    2024年02月05日
    浏览(49)
  • QT网络通信-TCP、UDP通信

    时间记录:2024/1/17 pro文件添加模块network (1)创建TCP服务器对象 QTcpServer (2)为 QTcpServer 对象的 newConnection 信号绑定槽,用来监听TCP客户端的新连接,有新的客户端连接便会触发此信号 (3)使用 nextPendingConnection 方法获取连接的Tcp客户端对象 QTcpSocket (4)为 QTcpSocket 的 r

    2024年01月18日
    浏览(58)
  • 【Unity】网络通信(TCP&UDP)

    Unity/C#要想和其他电脑或者软件程序通讯,最好的方式是通过网络进行通讯,下面简要介绍以下其原理和实现: TCP和UDP是传输层协议,使用IP协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。 两者的不

    2024年01月16日
    浏览(69)
  • 网络通信(Socket/TCP/UDP)

    Socket(又叫套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接协议,客户端的IP地址,客户端的端口,服务器的IP地址,服务器的端口。 一个Socket是一对IP地址和端口。 Socket可以看

    2024年01月22日
    浏览(56)
  • 基于UDP/TCP的网络通信编程实现

    红色是心中永不褪色的赤诚 操作系统为网络编程提供了 Socket api , Socket是基于TCP/IP协议的网络通信的基本单元, 基于Socket的网络程序开发就是 网络编程. 由于直接与应用层联系的是传输层, 所以针对应用层协议(TCP, UDP), Shocket提供了三种套接字, 分别是 流套接字(使用TCP) , 数据报

    2024年02月08日
    浏览(55)
  • day2:TCP、UDP网络通信模型

    思维导图 机械臂实现 按下后机械臂反应

    2024年01月16日
    浏览(44)
  • 使用 python socket 实现UDP/TCP网络通信

    目录 目录 1.socket简介 2.创建socket 2.1创建UDPSocket 2.2创建TCPSocket 3.使用UDPSocket发送数据并接收 4.使用UDPSocket发送广播 5.UDPSocket聊天器 (多线程实现消息的收发功能) 6.使用TCPSocket建立客户端 7.使用TCPSocket建立服务端        socket(简称:套接字),是支持TCP和UDP(网络传输方式

    2023年04月10日
    浏览(65)
  • 【Java 网络编程】网络通信原理、TCP、UDP 回显服务

    互联网从何而来? 这要追溯到上个世纪 50 - 60 年代,当时正逢美苏争霸冷战, 核武器 给战争双方提供了足够的威慑力,想要保全自己,就要保证自己的 反制手段 是有效的。 如何保证能够反击: 保存指挥机构 保存核弹头和发射井 指挥机构和核弹头之间的通信链路 需要保证

    2023年04月10日
    浏览(50)
  • tcp/udp socket 网络通信中超时时间的设置

    1.connect函数的超时时间设置只对TCP有效 UDP由于是无连接的connect都会返回success 有两种方法: 第一种方法 默认的socket是阻塞模式 我们只需要设置其为非阻塞模式,然后调用select去查询其状态 代码如下:  第二种是 默认其为阻塞模式  通过setsockopt 函数设置TCP_SYNCNT 值 头文件

    2024年02月15日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包