套接字编程UDP

1.创建套接字

int socket(int domain, int type, int protocol);
第一个参数,底层用的ip报文统一使用的网络协议都是AFIN

第二个参数,面向流的传输协议

SOCK_DGRAM(数据报套接字类型):支持数据报(无连接、不可靠且具有固定最大长度的消息 )
第三个参数,设置为0
创建成功返回一个文件描述符,创建失败返回-1

2.绑定socket信息,ip和端口

2.1 填充sockaddr_in 结构体

IP信息和端口信息一定要发送到网络

(1)本地格式转化成网序列

local.sin_port = htons(_port);
将本地字节序(也叫主机字节序 )的端口号,转换为网络字节序(大端序 高字节存低地址,低字节存高地址),从而让端口号能在网络通信中正确识别和传输
eg:主机是小端序(如常见的 x86 架构 ),_port 的值是 8080(十进制 ),在主机内存中以小端序存储(低字节在前 ),二进制可能表示为 0x1F 0x20(十六进制拆分 )。经过 htons 转换后,会变成大端序的 0x20 0x1F ,然后赋值给 local.sin_port ,满足网络字节序要求

(2)ip也是一样

  1. ip转化为4字节
  2. 4字节转化为网络序列
    1.点分十进制 -> 4字节二进制(主机字节序)
    eg:IP 地址 192.168.1.100
    192 -> 11000000
    168 -> 10101000
    1 -> 00000001
    100 -> 01100100
    得到32位二进制 (4字节)
    11000000 10101000 00000001 01100100
  3. 4字节 -> 大端序
    就能存到 sockaddr_in 结构体的 sin_addr.s_addr 成员里,供网络操作使用
    local.sin_addr.s_addr = inet_addr(_ip.c_str());
    函数申明 in_addr_t inet_addr(const char *cp);
    在实际编程中,我们不需要手动写 in_addr_t inet_addr(const char *cp); 这个声明,而是通过包含头文件 #include <arpa/inet.h> 来获取该函数的声明
    函数调用 local.sin_addr.s_addr = inet_addr(_ip.c_str());
    local.sin_addr.s_addr = inet_addr("192.168.1.100");

    不管是内网还是公网的客户端,都能访问到服务,就可以用 INADDR_ANY ,不用关心具体绑定哪个 IP
    INADDR_ANY 的核心作用就是让服务器「绑定到本机所有可用的网络接口」,从而实现:

无论客户端通过服务器的公网 IP、内网 IP 还是本地回环地址(127.0.0.1) 发送请求,只要端口正确,服务器都能接收到。
无需提前知道服务器有哪些 IP 地址(比如服务器可能有多个网卡,或 IP 是动态分配的),简化配置

recvfrom 和 sendto 函数

服务器要显示bind,ip和端口号必须是众所周知且不能轻易改变的

  1. 收消息,客户端要给服务器发消息,为了让服务端处理数据
    recvfrom 接收数据
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

client的bind

client要访问目标服务器,需要知道服务器ip和端口,而客户端和服务器是同一家公司写的,就能知道
客户端需要bind即使是客户端,发送数据时也需要一个「源端口」,让服务器能通过 recvfrom 获取客户端的端口。但不要显示地bind,首次发消息,os会自动给client进行bind,os知道ip,os随机选择端口号,只要端口号是唯一的就可以
(1)服务端必须「显式绑定」
服务端需要一个固定、已知的端口(比如 80、8080),让客户端能主动连接。因此必须手动 bind:

(2)客户端可以「隐式绑定」
客户端不需要固定端口(端口由系统自动分配),因此可以省略 bind 操作。当客户端第一次调用 sendto 或 recvfrom 时:

操作系统会自动为客户端分配一个随机的空闲端口(通常在 1024~65535 范围内)
同时自动绑定客户端的 IP(通常是本机 IP,如 192.168.1.100)

操作系统会自动完成以下步骤:

检查客户端套接字是否已绑定端口:
如果未绑定,进入「自动绑定流程」。
分配随机端口:
从 1024~65535 中选一个未被占用的端口(类似临时端口分配)。
绑定客户端 IP:
自动绑定到客户端的「默认出网 IP」(可能是 127.0.0.1 或本机真实 IP,由路由策略决定)


相关推荐
晚风吹人醒.几秒前
缓存中间件Redis安装及功能演示、企业案例
linux·数据库·redis·ubuntu·缓存·中间件
REDcker5 分钟前
tcpdump 网络数据包分析工具完整教程
网络·测试工具·tcpdump
Hard but lovely28 分钟前
linux: pthread库的使用和理解
linux
若汝棋茗1 小时前
在网络密林中传递轻盈信使 —— TouchSocket 的 UdpSession 探秘
网络
嵌入式-小王1 小时前
每天掌握一个网络协议----ICMP
网络·网络协议·ping
麦麦鸡腿堡1 小时前
Java_网络编程_InetAddress类与Socket类
java·服务器·网络
Awkwardx1 小时前
Linux网络编程—应用层协议HTTP
网络·网络协议·http
4***v2141 小时前
详解 为什么 tcp 会出现 粘包 拆包 问题
网络·tcp/ip·php
老前端的功夫2 小时前
前端浏览器缓存深度解析:从网络请求到极致性能优化
前端·javascript·网络·缓存·性能优化
这儿有一堆花2 小时前
Kali Linux:探测存活到挖掘漏洞
linux·运维·服务器