网络 UDP协议(C++

您所在的位置:网站首页 udp可靠的传输协议实现了吗 网络 UDP协议(C++

网络 UDP协议(C++

2024-06-02 03:27:06| 来源: 网络整理| 查看: 265

这里写目录标题 udp通信编程各端的操作流程:服务端操作流程:客户端操作流程:第2,3步与服务端不同 socket接口介绍udp客户服务端代码实现 推荐阅读

socket套接字编程就是在网络程序中编写代码,通过一套套的接字接口实现网络程序的编写。

udp通信编程

udp是无连接、不可靠、面向数据报的传输层协议。 特点:支持多对多连接交互通信。尽最大努力交付,不保证可靠性,但速度最快 在这里插入图片描述

各端的操作流程: 服务端操作流程: 创建套接字端口:在内核中创建socket结构体,关联进程与网卡之间的联系为套接字绑定地址信息:网络通信中的数据都必须带有源端IP、源端端口、对端IP、对端端口、协议。在内核创建的socket结构体中描述IP地址端口以及协议,(必须主动绑定,告诉客户端自己的地址信息,如果不绑定客户端就不知道该发往哪个服务端了)为了告诉操作系统发往哪个IP地址,哪个端口的数据是交给我来处理的接收数据:告诉操作系统发往哪个地址和端口的数据应该交给我处理,操作系统一旦接收到发往这个地址和端口的数据,就会将这条数据放到对应的socket的接收缓冲区中,然后服务端从对应的socket的接收缓冲区中取出数据。发送数据:将数据写入内核中的socket发送缓冲区中,操作系统选择合适的时候将数据封装发送出去关闭套接字:释放资源

在这里插入图片描述

客户端操作流程:第2,3步与服务端不同 创建套接字:在内核中创建socket结构体,关联进程与网卡之间的联系为套接字绑定地址信息:描述在内核中创建的socket结构体的源端地址信息;发送的数据中源端地址信息就是绑定的地址信息(不推荐主动绑定地址,降低端口冲突的概率,从而确保数据发送的安全性)发送数据:将数据放到socket的发送缓冲区中,操作系统选择合适时候封装数据并发送数据。若socket发送数据的时候还没绑定地址,则操作系统会选择合适的地址进行绑定。接收数据:将数据写入内核中的socket发送缓冲区中,操作系统选择合适的时候将数据封装发送出去关闭套接字:释放资源 socket接口介绍

1、创建套接字int socket(int domain, int type, int protocol) 参数内容(domian:地址域(本地通信-AF_LOCAL、IPv4-AF_INET、IPv6-AF_INET6等)确定本次socket通信使用哪种协议版本的地址结构,不同的协议版本有不同的地址结构;type:套接字类型(流式套接字-SOCK_STREAM、数据报套接字-SOCK_DGRAM等);protocol:协议类型(TCP-IPPROTO_TCP、UDP-IPPROTO_UDP) ,默认为0-流式默认TCP,数据报默认UDP) 返回值:文件描述符-非负整数, 套接字所有其他接口的操作句柄,失败返回-1

2、为套接字绑定地址信息int bind(int sockfd, struct sockaddr *addr, socklen_t len)参数内容(sockfd:创建套接字返回的操作句柄;addr:要绑定的地址信息;len:要绑定的地址信息长度) 中间的参数结构体有很多种

struct sockaddr { sa_family_t sa_family; char sa_data[14]; }; struct sockaddr_in { sa_family sin_family;//地址域 in_port_t sin_port;//端口号 struct in_addr sin_addr;//IP地址 }; struct sockaddr_in6 { sa_family sin_family;//地址域 in_port_t sin6_port;//端口号 uint32_t sin6_flowinfo; struct in6_addr, sin6_addr;//IP地址 unit32_t sin6_scope_id; } struct sockaddr_un { __SOCKADDR_COMMON (sun_); char sun_path[108]; };

在这里插入图片描述

不同的地址结构,有统一的一个信息:前两个字节是地址域类型,bind可以绑定不同的地址结构,为了实现接口统一,因此用户定义地址结构的时候,需要定义自己需要的地址结构,例如IPv4就使用struct sockaddr_in,但是进行绑定的时候,统一类型强转成为sockaddr*类型 简单解析bind接口的实现

bind(fd,addr, len) { if(addr->sa_family==AF_INET) { //绑定IPv4地址信息,这个结构体按照sockaddr_in进行解析 } else if (addr->sa_family==AF_INET6) { //绑定IPv6地址信息,这个结构体按照sockaddr_in6进行解析 } else if ... }

3、接收数据,接收发送者地址便于回复ssize_t recvfrom(int sockfd, char *buf, int len, int flag, struct sockaddr *peer_addr, socklen *addrlen) 参数内容(sockfd:创建套接字返回的操作句柄;buf:一块缓冲区,用于接收从接收缓冲区中取出数据;len:想要接收的数据长度;flag:操作选项标志,默认为0,表示阻塞操作;peer_addr:发送方的地址信息;addrlen:想要获取的地址信息长度以及返回实际长度) 返回值:成功返回实际接收到的数据字节长度,失败返回-1

4、发送数据ssize_t sendto(int sockfd, char *data, int len, int flag, struct sickaddr *peer_addr, socklen_t addrlen) 参数内容(socket:socket操作句柄;data:要发送的数据地址;len:要发送数据长度;flag:默认为0,表示阻塞操作;peer_addr:接收方的地址信息;addrlen:地址信息长度) 返回值:成功返回实际发送的数据字节长度,失败返回-1

5、关闭套接字int close(int fd)

网络字节序的转换接口 uint32_t htonl(uint32_t hostlong) 主机字节序到网络字节序的转换 uint16_t htons(uint16_t hostshort) uint32_t ntohl(uint32_t netlong)网络字节序到主机字节序的转换 uint16_t ntohs(uint16_t netshort)

in_addr_t inet_addr(const char *cp)将字符串的点分十进制IP地址转换成为网络字节序的整数IP地址 char *inet_ntoa(struct in_addr in)将网络字节序的整数IP地址转化为字符串点分十进制IP地址 const char *inet_ntop(int af, const void *src,char *dst, socklen_t size)将网络字节序的整数IP地址转化为字符串IP地址-兼容IPv4和IPv6 int inet_pton(int af, const char *src, void *dst)将字符串的IP地址转换成为网络字节序的整数IP地址-兼容IPv4和IPv6

udp客户服务端代码实现

使用c++封装UdpSocket类,实例化的每一个对象都是一个udp通信套接字,并且能够通过成员接口实现udp通信流程 udpsocket.hpp

//udpsocket.hpp #include #include #include #include #include #include using namespace std; class UdpSocket { public: UdpSocket() :_sockfd(-1) {} //创建套接字 bool Socket() { _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (_sockfd //定义IPv4地址结构体 struct sockaddr_in addr; //地址信息赋值 addr.sin_family = AF_INET; addr.sin_port = htons(port);//将主机字节序短整型型数据转化为网络字节序数据 addr.sin_addr.s_addr = inet_addr(ip.c_str());//将字符串IP地址转化为网络字节序IP地址 socklen_t len = sizeof(struct sockaddr_in); int ret = bind(_sockfd, (struct sockaddr*)&addr, len); if (ret struct sockaddr_in peer_addr;//用于接收发送端的地址信息 socklen_t len = sizeof(struct sockaddr_in); char tmp[4096] = {0}; int ret = recvfrom(_sockfd, tmp, 4096, 0, (struct sockaddr*)&peer_addr, &len); if (ret *port = ntohs(peer_addr.sin_port);//网络字节序到主机字节序的转换 } if (ip != NULL) { *ip = inet_ntoa(peer_addr.sin_addr);//网络字节序到字符串IP地址的转换 } return true; } //发送数据 bool Send(const string &data, string &ip, const uint16_t port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(ip.c_str()); socklen_t len = sizeof(struct sockaddr_in); int ret = sendto(_sockfd, data.c_str(), data.size(), 0, (struct sockaddr*)&addr, len); if (ret if (_sockfd > 0) { close(_sockfd); _sockfd = -1; } return true; } private: int _sockfd; };

udp_srv.cpp

#include #include #include "udpsocket.hpp" using namespace std; #define CHECK_RET(q) if((q)==false){return false;} int main(int argc, char *argv[]) { //运行时有三个参数 udp_src 192.168.73.29 4096 if (argc != 3) { cout if (argc != 3) { cout


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭