套接字编程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,由路由策略决定)


相关推荐
bugtraq202121 分钟前
为什么.NET的System.IO.Compression无法解压zlib流
linux·运维·服务器
咖啡教室25 分钟前
每日一个计算机小知识:Linux
linux·后端
江湖人称小鱼哥2 小时前
WSL + Docker 网络访问详解
网络·docker·容器·wsl
江公望2 小时前
Qt的QT_QPA_EGLFS_INTEGRATION环境变量浅解
linux·qt·qml
YuCaiH2 小时前
网络编程的基础知识
linux·笔记·嵌入式·网络通信
Siren_dream3 小时前
在VMware上运行Linux(我选择的是Ubuntu)
linux·运维·ubuntu
☆璇3 小时前
【Linux】Socket编程UDP
linux·网络·udp
嵌入式小能手3 小时前
飞凌嵌入式ElfBoard-Vim编辑器之Vim常用操作命令
linux·编辑器·vim
迷路爸爸1803 小时前
源码编译安装最新 tmux 教程(含 Debian/Ubuntu/CentOS/Arch/macOS 等系统)
linux·ubuntu·macos·centos·debian·tmux·archlinux
励志不掉头发的内向程序员4 小时前
【Linux系列】掌控 Linux 的脉搏:深入理解进程控制
linux·运维·服务器·开发语言·学习