Day3:Windows网络编程-UDP

news2024/11/25 2:31:57

  对比TCP与UDP的通信区别

 UDP Server没有listen()和accept()

TCP Server

#include <iostream>
#include <WinSock2.h>
// 包含网络库
#pragma comment(lib,"ws2_32.lib")
using namespace std;

int main()
{
	// 1. 初始化套接字 初始化套接字库
	cout << "UDP Server" << endl;
	WORD wVersion;
	WSADATA wsaData;
	int err;
	wVersion = MAKEWORD(1, 1);
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0)
	{
		return err;
	}
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		return -1;
	}

	// 2. 创建套接字
	SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
	if (INVALID_SOCKET == sockSrv) //加入容错机制 
	{
		printf("socket errorNo = %d\n",GetLastError());
		return -1;
	}


	// 3.分配地址和端口
	SOCKADDR_IN addrSrv;
	// h:host to n:net l:long 主机字节序转换为网络字节序
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6001);

	if(SOCKET_ERROR == bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN)))
	{
		printf("bind errorNo = %d\n",GetLastError());
		return -1;
	}

	// 4. 等待接收数据
	SOCKADDR_IN addrCli; // 目的套接字地址族
	int len = sizeof(SOCKADDR_IN);
	char recvBuf[100] = {0};
	char sendBuf[100] = {0};
	while(true)
	{
		recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrCli, &len);
		cout << recvBuf << endl;

		sprintf_s(sendBuf, 100, "Ack:%s", recvBuf);
		sendto(sockSrv, sendBuf,strlen(sendBuf) + 1,0, (SOCKADDR*)&addrCli, len);
		
	
	}
	// 5. 关闭套接字
	closesocket(sockSrv);
	WSACleanup();
	system("pause");
	return 0;
}

代码逻辑:

  1. 初始化套接字 初始化套接字库
  2. 创建套接字
  3. 分配地址和端口
  4. bind() 分配地址和端口
  5. 等待接收数据 recvfrom()接收数据 sendto()发送数据  while循环

TCP Client

#include <iostream>
#include <WinSock2.h>
// 包含网络库
#pragma comment(lib,"ws2_32.lib")
using namespace std;

int main()
{
	// 1. 初始化套接字 初始化套接字库
	cout << "UDP Client" << endl;
	WORD wVersion;
	WSADATA wsaData;
	int err;
	wVersion = MAKEWORD(1, 1);
	err = WSAStartup(wVersion, &wsaData);
	if (err != 0)
	{
		return err;
	}
	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		return -1;
	}

	// 2. 创建UDP套接字
	SOCKET sockCli = socket(AF_INET, SOCK_DGRAM, 0);
	if (INVALID_SOCKET == sockCli) //加入容错机制 
	{
		printf("socket errorNo = %d\n", GetLastError());
		return -1;
	}

	// 3. 填充地址和端口
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6001);

	int len = sizeof(SOCKADDR_IN);
	char sendBuf[100] = "hello";
	char recvBuf[100] = { 0 };

	// 4.发送UDP数据
	sendto(sockCli, sendBuf, strlen(sendBuf) + 1,0,(SOCKADDR*)&addrSrv, len);

	// 5.接收UDP数据
	recvfrom(sockCli,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
	cout << recvBuf << endl;
	closesocket(sockCli);
	system("pause");
	return 0;
}

代码逻辑:

  1. 初始化套接字 初始化套接字库
  2. 创建UDP套接字
  3. 填充地址和端口
  4. 直接发送/接收数据

运行结果:

关于bind()函数

官方文档:绑定函数将本地地址与套接字相关联。

int bind(
  [in] SOCKET         s,
       const sockaddr *addr,
  [in] int            namelen
);

bind()是一个用于将套接字(socket)与特定的网络地址(IP 地址和端口号)绑定的函数。它在套接字创建后,但在进行网络通信之前被调用。

三个参数的含义:

  • sockfd:需要绑定的套接字描述符(socket descriptor)。
  • addr:指向要绑定的网络地址的结构体指针,通常是 struct sockaddr 或其派生结构体的指针。
  • addrlen:网络地址结构体的长度。

关于sendto()函数

官方文档:

sendto 函数将数据发送到特定目标。

int WSAAPI sendto(
  [in] SOCKET         s,
  [in] const char     *buf,
  [in] int            len,
  [in] int            flags,
  [in] const sockaddr *to,
  [in] int            tolen
);

sendto() 是用于发送数据到指定目标地址的函数,通常用于无连接的数据报套接字(SOCK_DGRAM)。它可以向指定的目标地址发送数据,并指定数据的长度和其他参数。

参数的含义:

  • s:要发送数据的套接字描述符(socket descriptor)。
  • buf:指向包含要发送的数据的缓冲区的指针。
  • len:要发送的数据的长度。
  • flags:发送标志,用于控制发送操作的行为,例如是否启用特定的选项。
  • to:指向目标地址的结构体指针,通常是 struct sockaddr 或其派生结构体的指针。
  • tolen:目标地址结构体的长度。

关于recvfrom()函数

官方文档:

recvfrom 函数接收数据报并存储源地址。

int recvfrom(
  [in]                SOCKET   s,
  [out]               char     *buf,
  [in]                int      len,
  [in]                int      flags,
  [out]               sockaddr *from,
  [in, out, optional] int      *fromlen
);

recvfrom() 是用于接收来自指定源地址的数据的函数,通常用于无连接的数据报套接字(SOCK_DGRAM)。它可以从指定的源地址接收数据,并存储到指定的缓冲区中。

参数含义:

  • s:要接收数据的套接字描述符(socket descriptor)。
  • buf:指向接收数据的缓冲区的指针。
  • len:缓冲区的长度,即最大接收的字节数。
  • flags:接收标志,用于控制接收操作的行为,例如是否启用特定的选项。
  • from:指向存储源地址的结构体的指针,通常是 struct sockaddr 或其派生结构体的指针。
  • fromlen:指向存储源地址结构体长度的整型指针。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/579132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt编写视频监控系统76-Onvif跨网段组播搜索和单播搜索的实现

一、前言 在视频监控行业一般会用国际onvif工具来测试设备是否支持onvif协议&#xff0c;工具的名字叫ONVIF Device Manager&#xff08;还有个工具叫ONVIF Device Test Tool&#xff0c;专用于程序员测试各种数据交互&#xff09;&#xff0c;可以自行搜索下载&#xff0c;此…

linux网桥简单理解和持久化配置

文章目录 前言一、Linux 网桥是什么&#xff1f;二、网桥主要作用三、网桥配置命令及安装(CentOS系统)1 网桥配置命令2.持久化网桥配置 前言 linux bridge是网络虚拟化中非常重要的一种设备&#xff0c;今天就来学习下linux bridge的相关知识 一、Linux 网桥是什么&#xff1…

Allegro操作规范

光绘输出操作规范 1.1添加钻孔表 添加钻孔表的具体步骤为: 1.通过屏幕右边的Visibility选项的Views列表,将Drill层打开 2.将Visibility选项中的PIN和Via选项都选中,见下图所示: 1.2添加钻孔文件 参数设好之后关闭NC Drill/Parameters窗口,输出数控机床钻孔文件的命…

企业域名与企业邮箱:提升企业形象的必备选择

在商业中&#xff0c;你最不想做的就是把注意力从业务上移开&#xff0c;去担心一些小事——比如电子邮件。大多数免费的企业电子邮件账户偷工减料&#xff0c;因此无法交付货物。在Zoho我们围绕您的需求设计了我们的平台&#xff0c;以创建优于其他工作电子邮件地址的电子邮件…

jQuery-从左到右、从右到左

<!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <title>从左到右、从右到左</title> <style type"text/css"> select { …

采购申请审批测试

采购申请审批的配置并不难&#xff0c;但是总会有原因导致业务无审批策略&#xff0c;而且这个配置也比较脆弱&#xff0c;有时同步也会出现问题&#xff0c;小编利用这篇操作记录下测试结果。 1、项目类别的审批策略分类 下图是审批策略分类-项目类别不给值&#xff0c;测试…

LAMP架构中的安装论坛

前言&#xff1a;本次操作依赖于LAMP的环境已经配置完全&#xff0c;网站也是依赖于开发人员现有的网站包框架&#xff0c;实施在LAMP已搭建好的环境进行安装部署 目录 一、对mysql进行操作 创建数据库&#xff0c;并进行授权 二、解压论坛压缩包 三、初步访问安装 解决…

少年,你可听说过MVCC?

&#xff1a;切&#xff01;这谁没听过&#xff0c;不就是多版本并发控制么~ 早在亘古时期&#xff0c;修真界就流传着一门mysql功法&#xff0c;将其修至小乘境界&#xff0c;足以纵横一方。。。不乏也有走火入魔者&#xff0c;为祸一方~ Serializable篇 强制事务排序&#…

【MCS-51】中断系统原理及应用

中断是单片机中一个十分重要的功能&#xff0c;它的出现能够让我们的单片机在顺序执行命令时&#xff0c;具备应对特殊情况的能力。 目录 &#x1f319;通信方式 &#x1f343;无条件传送 &#x1f343;有条件传送 &#x1f343;DMA通信 &#x1f343;中断传送 &#x1…

python计算程序开始、结束以及运行的时间

python 计算程序运行的耗时&#xff0c;主要有三种方法&#xff1a; time.time() 、 time.perf_counter() 和 datetime.datetime.now()方法 使用方法如下&#xff1a; 1. time.time() import time start time.time() # 程序开始时间,单位为秒 print("start_time:&…

C++ [STL之list的使用]

本文已收录至《C语言和高级数据结构》专栏&#xff01; 作者&#xff1a;ARMCSKGT 前言 vector是一片连续的空间&#xff0c;在数据访问上性能较好&#xff0c;但是任意位置插入删除性能较低&#xff0c;头插头删性能亦是如此&#xff1b;此时在这种需要频繁插入的场景下&…

PCL计算法向量结果不对的问题

一、点云&#xff08;高程渲染。CC计算的法向量&#xff0c;Z分量渲染&#xff09; 高程渲染 法向量Z分量的绝对值渲染 二、PCL计算法向量 下面是PCL计算法向量的代码&#xff08;点类型自己设置的&#xff09; 计算出的法向量有正有负 void pclNormalEstimation(pcl::Point…

【C++】构造函数初始化列表的特性以及注意事项

文章目录 一、1.1构造函数体赋值&#xff1a;二、 初始化列表2.1初始化基本形式&#xff0c;注意&#xff1a;3. 尽量使用初始化列表初始化&#xff0c;因为不管你是否使用初始化列表&#xff0c;对于自定义类型成员变量&#xff0c;一定会先使用初始化列表初始化。4. 成员变量…

JavaScript教程(二)

BOM浏览器对象模型 什么是BOM BOM&#xff08;Browser Object Model&#xff09;即浏览器对象模型&#xff0c;它提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是 window&#xff1b;BOM由一系列相关的对象构成&#xff0c;并且每个对象都提供了很多方…

deepfloyd/IF

Stable Diffusion团队放大招&#xff01;新绘画模型直出AI海报&#xff0c;实现像素级图像生成AI画文字终于能画对了https://mp.weixin.qq.com/s/_pwBD4-wLA9zNHBpD6WdNgDeepFloyd IF — DeepFloydhttps://deepfloyd.ai/deepfloyd-ifhttps://colab.research.google.com/#scroll…

微服务开发系列 第八篇:Elasticsearch

总概 A、技术栈 开发语言&#xff1a;Java 1.8数据库&#xff1a;MySQL、Redis、MongoDB、Elasticsearch微服务框架&#xff1a;Spring Cloud Alibaba微服务网关&#xff1a;Spring Cloud Gateway服务注册和配置中心&#xff1a;Nacos分布式事务&#xff1a;Seata链路追踪框架…

gradle快速入门

1.Gradle 入门 1.1 Gradle 简介 Gradle 是一款Google 推出的基于JVM、通用灵活的项目构建工具&#xff0c;支持Maven&#xff0c;JCenter 多种第三方仓库;支持传递性依赖管理、废弃了繁杂的xml 文件&#xff0c;转而使用简洁的、支持多种语言(例如&#xff1a;java、groovy 等…

如何成功申请计算机软件著作权【申请流程完整记录】

致谢 &#xff1a;此博文的编写包括软著的申请&#xff0c;均借鉴了大佬【万里守约】的博客&#xff0c;很幸运一次性通过 — 提示&#xff1a;此博文仅适合个人申请&#xff0c;因为我是自己一个人的项目&#xff0c;自己一个人申请软著 文章目录 前言&#xff1a;一、网站注册…

HCIA-RSTP,MSTP

目录 STP的不足 RSTP对STP的改进 1&#xff0c;配置BPDU的处理发生变化&#xff1a; 2&#xff0c;配置BPDU的格式发生变化&#xff0c;充分利用STP的flag字段&#xff0c;明确接口角色。 3&#xff0c;RSTP拓扑处理&#xff1a; 端口角色&#xff1a; MSTP&#xff08;多…

Inline HOOK

一、Inline HOOK介绍 1、内联钩子简介 Inline hook&#xff08;内联钩子&#xff09;是一种在程序运行时修改函数执行流程的技术。它通过修改函数的原始代码&#xff0c;将目标函数的执行路径重定向到自定义的代码段&#xff0c;从而实现对目标函数的拦截和修改。 内联钩子通…