论坛网站开发深圳国外网站设计
网络编程-socket&UDP网络程序
01. 基础知识
1.1 IP地址
IP地址互联网协议地址,用于标识网络中的设备。通俗来说,IP地址就像你家的门牌号,它能让网络中的数据准确找到要去的设备。比如,当你在手机上访问一个网站时,你的手机会有一个 IP地址,网站服务器也有一个IP地址,数据就是通过这两个地址在设备之间传递的。
1.1.1 IPv4
- 32位地址(4字节),点分十进制表示(192.168.1.1)
- 地址分类:A类(1-126)、B类(128-191)、C类(192-223)
1.1.2 IPv6
- 128位地址,冒号分隔十六进制表示,用来解决IPv4地址枯竭问题
1.2 端口号
端口号是由16位无符号整数(0-65535),用来标识主机上的特定服务。同一主机上的不同服务通过端口号区分
- 分类:
- 0-1023:知名端口(HTTP:80,HTTPS:443,SSH:22,...)
- 1024-49151:注册端口(MySQL:3306,…)
- 49152-65535:动态/私有端口(客户端临时使用)
 
- 0-1023:知名端口(

1.3 端口号与进程PID
端口号用于标识进程,进程PID也是用于标识进程,为什么在网络中,不直接使用进程PID呢?

- 进程号(PID):由系统动态分配,不同主机上大概率不同,难以基于此实现跨主机通信。
- 端口号:网络协议的一部分,是主机通过网卡通信的必经软通道,有固定约定(如80、23、443),基于固定值建立通信更直接可靠。
- Windows开发约定:避免使用1024以前的端口,建议使用1024-65535区间的端口号。
- 并不是所有的进程都需要进行网络通信,如果端口号、,无疑会影响网络管理的效率PID都使用同一个解决方案,会影响网络管理效率。

1.4 传输层协议
- TCP:
- 面向连接、可靠传输,字节流
- 三次握手建立连接,四次挥手断开连接
- 流量控制、拥塞控制
- 适用场景:文件传输、网页浏览、邮件
- TCP 流程:socket()→bind()→listen()→accept()(服务器);socket()→connect()(客户端);之后用send()/recv()通信。
 
- UDP:
- 无连接、不可靠传输,数据报
- 低延迟、无拥塞控制
- 适用场景:视频流、DNS查询、游戏实时数据
- UDP 流程:socket()→bind()(可选);用sendto()/recvfrom()直接通信。
 
1.5 网络字节序
由于不同CPU架构使用不同字节序(大端/小端)。所以TCP/IP 协议规定网络中传输的数据,统一采用大端存储方案,也就是网络字节序,现在大端/小端称为主机字节序。
1.5.1 字节序转换函数
#include <arpa/inet.h>// 16位转换
uint16_t htons(uint16_t hostshort);  //short常用于端口号 主机->网络
uint16_t ntohs(uint16_t netshort);   //long常用于 IP 地址 网络->主机// 32位转换
uint32_t htonl(uint32_t hostlong);
uint32_t ntohl(uint32_t netlong);
1.5.2 IP地址转换函数
// 将点分十进制 IPv4 字符串转为网络字节序整数。
in_addr_t inet_addr(const char *cp);
int inet_pton(int af, const char *src, void *dst);// 将网络字节序 IPv4 整数转为点分十进制字符串(线程不安全)。
char *inet_ntoa(struct in_addr in);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
02. socket 套接字
socket 套接字提供了下面这一批常用接口,用于实现网络通信。
2.1 socket 常见API
2.1.1 socket()
创建一个socket描述符,用于后续网络操作。
int socket(int domain, int type, int protocol);
- 参数:
- domain:协议族,- AF_INET(IPv4)、- AF_INET6(IPv6)…
- type:socket 类型,- SOCK_STREAM、- SOCK_DGRAM
- protocol:协议类型,通常为 0
 
- 返回值:成功返回socket描述符即文件描述符,失败返回 -1
2.1.2 bind()
将 socket 与特定的IP和port绑定(主要用于服务器)。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 参数:
- sockfd:- socket()返回的文件描述符
- addr:指向- sockaddr或- sockaddr_in的指针,包含要绑定的地址信息
- addrlen:- addr结构体的大小
 
- 返回值:成功 0,失败-1
注意: bind()接收 sockaddr* 类型,需将 sockaddr_in* 转换为 sockaddr*如:
struct sockaddr_in serv_addr;
bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
2.1.3 sendto() 和 recvfrom()
- 
sendto():向指定地址发送数据。 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);- dest_addr:目标主机的地址信息。
 
 
- 
recvfrom():从指定地址接收数据。 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);- src_addr:输出参数,存储发送方的地址信息(可设为- NULL)。
 
2.1.4close()
关闭 socket 描述符,释放资源。
int close(int fd);
2.2 sockaddr 结构体详解
struct sockaddr {sa_family_t sa_family;  // 地址族char        sa_data[14]; // 地址数据(变长,依地址族而定)
};
socket网络通信标准隶属于POSIX通信标准,该标准的设计初衷就是为了实现 可移植性,程序可以直接在使用该标准的不同机器中运行,但有的机器使用的是网络通信,有的则是使用本地通信,socket套接字为了能同时兼顾这两种通信方式,提供了sockaddr结构体
由sockaddr结构体衍生出了两个不同的结构体:sockaddr_in网络套接字、sockaddr_un域间套接字,前者用于网络通信,后者用于本地通信
- sockaddr是通用的地址结构体。
- 可以根据16位地址类型,判断是网络通信,还是本地通信
- 在进行网络通信时,需要提供IP、port等网络通信必备项,本地通信只需要提供一个路径名,通过文件读写的方式进行通信(类似于命名管道)

socket提供的接口参数为sockaddr*,我们既可以传入&sockaddr_in进行网络通信,也可以传入&sockaddr_un进行本地通信,传参时将参数进行强制类型转换即可,这是使用 C语言实现多态的典型做法,确保该标准的通用性。
2.2.1 sockaddr _in定义
sockaddr_in 定义在 <netinet/in.h> 头文件中,其核心作用是存储 IPv4 协议的地址信息,包括IP、port、协议族等。在 socket 编程中,很多函数(如 bind()、connect()、recvfrom() 等)需要接收一个 sockaddr类型的指针作为参数,而 sockaddr_in 是 sockaddr 针对IPv4的 “具体化” 实现。
2.2.2 sockaddr _in结构体成员
struct sockaddr_in {sa_family_t    sin_family;   // 地址族(必须为 AF_INET)in_port_t      sin_port;     // 端口号(网络字节序)struct in_addr sin_addr;     // IPv4 地址(网络字节序)char           sin_zero[8];  // 填充字段,使结构体大小与 sockaddr 一致
};
2.2.3 sin_addr
struct in_addr(嵌套结构体,用于存储 IPv4 地址)。s_addr 存储 32 位 IPv4 地址。
struct in_addr {in_addr_t s_addr;  // IPv4 地址(32位整数,网络字节序)
};
注意:必须使用网络字节序。
- 直接赋值:sin_addr.s_addr = inet_addr("192.168.1.1");(inet_addr()自动转换为网络字节序)。
- 绑定任意地址:sin_addr.s_addr = INADDR_ANY;(表示监听本机所有网卡的IP地址)。
sockaddr_in 是 sockaddr 针对IPv4的专用版本,两者大小相同(16 字节),可通过强制类型转换互相兼容。
03. 网络程序
加载中…
