贵阳网站seo,光谷做网站推广哪家好,汕头网站制作找谁,高级网站建设费用一.套接字类型
1.面向连接的套接字#xff08;SOCK_STREAM#xff09;
特点#xff1a;
传输过程中数据不会消失按顺序传输数据传输的数据不存在数据边界
2.面向消息的套接字#xff08;SOC_DGRAM#xff09;
特点#xff1a;
强调快速传输而非传输顺序传输的数据可…一.套接字类型
1.面向连接的套接字SOCK_STREAM
特点
传输过程中数据不会消失按顺序传输数据传输的数据不存在数据边界
2.面向消息的套接字SOC_DGRAM
特点
强调快速传输而非传输顺序传输的数据可能丢失也可能损毁传输的数据有数据边界限制每次传输的数据大小 二.地址信息的表示
1.结构体 sockaddr_in 的成员分析
struct sockaddr_in {sa_family_t sin_family; // 地址族一般为AF_INETin_port_t sin_port; // 端口号struct in_addr sin_addr; // IPv4地址char sin_zero[8]; // 用于对齐的填充字段
};
sin_family 每种协议族适用的地址族均不同用来存储协议地址族区分协议sin_port保存16位端口号并且是以网络字节序保存sin_addr保存32位IP地址信息并且也以网络字节序保存sin_zero无特殊含义。
三.网络字节序和地址变换
1.字节序和网络字节序
00000000 00000000 00000000 00000001 //小端序格式00000001 00000000 00000000 00000000 //大端序格式
cpu向内存保存数据的方式有2种这意味着cpu解析数据的方式也有两种。
在网络传输数据时约定统一方式也就是网络字节序统一为大端序。即先把数据数组转换为大端序格式再进行网络传输。
2.字节序转换
在网络编程中字节序转换是指将数据在不同字节序大端字节序和小端字节序之间进行转换的过程。在进行网络通信时为了确保数据在发送和接收的过程中能够正确解析需要进行字节序的转换。 常用的字节序转换函数有以下两个 htons和ntohs用于16位无符号整数的字节序转换。
htonshost to network short用于将主机字节序转换为网络字节序。ntohsnetwork to host short用于将网络字节序转换为主机字节序。
htonl和ntohl用于32位无符号整数的字节序转换。
htonlhost to network long用于将主机字节序转换为网络字节序。
ntohlnetwork to host long用于将网络字节序转换为主机字节序。
这些函数可以帮助我们在不同字节序之间进行转换确保数据在网络传输过程中的正确性和可靠性。例如如果要将一个16位整数从主机字节序转换为网络字节序可以使用htons函数进行转换uint16_t hostValue 0x1234;
uint16_t networkValue htons(hostValue);
//类似地如果要将一个32位整数从主机字节序转换为网络字节序可以使用htonl函数进行转换uint32_t hostValue 0x12345678;
uint32_t networkValue htonl(hostValue);
//在接收数据时可以使用相应的ntohs和ntohl函数将网络字节序转换为主机字节序。
3.网络地址的初始化与分配
1inet_addr 函数 用于将IPv4地址的点分十进制表示形式转换为32位无符号整数。它位于arpa/inet.h 头文件中并且返回类型是in_addr_t。在使用inet_addr函数时需要检查返回值是否等于INADDR_NONE以判断是否转换成功。如果返回值等于INADDR_NONE(-1)则表示转换失败可能是因为输入的IP地址格式不正确。
#include iostream
#include arpa/inet.hint main() {const char* ipStr 192.168.0.1;// 将点分十进制形式的IPv4地址转换成32位无符号整数in_addr_t ipAddr inet_addr(ipStr);if (ipAddr INADDR_NONE) {std::cout Invalid IP address std::endl;} else {std::cout IP address in network byte order: ipAddr std::endl;}return 0;
}in_addr_t inet_addr(const char *cp);inet_addr函数转换网络主机地址如192.168.1.10)为网络字节序二进制值如果参数char *cp无效函数返回-1(INADDR_NONE),这个函数在处理地址为255.255.255.255时也返回1,255.255.255.255是一个有效的地址不过inet_addr无法处理;2inet_pton 函数 一个用于将IPv4和IPv6地址字符串转换为网络字节序的二进制形式的函数。若成功则返回值为1否则返回值为0.
#include iostream
#include arpa/inet.hint main() {const char* ipv4Address 192.168.0.1;struct in_addr ipv4Binary;if (inet_pton(AF_INET, ipv4Address, ipv4Binary) 0) {std::cout IPv4 address in binary form: 0x std::hex ntohl(ipv4Binary.s_addr) std::endl;} else {std::cout Invalid IPv4 address std::endl;}const char* ipv6Address 2001:0db8:85a3:0000:0000:8a2e:0370:7334;struct in6_addr ipv6Binary;if (inet_pton(AF_INET6, ipv6Address, ipv6Binary) 0) {std::cout IPv6 address in binary form: ;for (int i 0; i 16; i) {std::cout std::hex static_castint(ipv6Binary.s6_addr[i]);}std::cout std::endl;} else {std::cout Invalid IPv6 address std::endl;}return 0;
}3inet_ntop 函数 一个用于将二进制形式的IPv4或IPv6地址转换回点分十进制表示的函数该函数不涉及字节序的转换。返回值若成功则为指向结构的指针若出错则为NULL。
#include iostream
#include arpa/inet.hint main() {// IPv4地址转换struct in_addr ipv4Addr;inet_pton(AF_INET, 192.168.0.1, (ipv4Addr.s_addr));char ipv4Str[INET_ADDRSTRLEN];inet_ntop(AF_INET, (ipv4Addr.s_addr), ipv4Str, INET_ADDRSTRLEN);std::cout IPv4 address: ipv4Str std::endl;// IPv6地址转换struct in6_addr ipv6Addr;inet_pton(AF_INET6, 2001:0db8:85a3:0000:0000:8a2e:0370:7334, (ipv6Addr.s6_addr));char ipv6Str[INET6_ADDRSTRLEN];inet_ntop(AF_INET6, (ipv6Addr.s6_addr), ipv6Str, INET6_ADDRSTRLEN);std::cout IPv6 address: ipv6Str std::endl;return 0;
}4网络地址初始化 客户端服务器初始化只需要将IP地址参数设置为 INADDR_ANY自动获取服务端的IP地址
#include iostream
#include arpa/inet.h // 包含网络地址相关的头文件int main() {// 初始化网络地址结构struct sockaddr_in serverAddress;serverAddress.sin_family AF_INET; // 设置地址族为IPv4serverAddress.sin_port htons(8080); // 设置端口号使用htons函数进行字节序转换serverAddress.sin_addr.s_addr inet_addr(192.168.0.1); // 设置IP地址使用inet_addr函数将字符串IP转换为二进制形式// 打印初始化的网络地址信息std::cout IP地址: inet_ntoa(serverAddress.sin_addr) std::endl; // 使用inet_ntoa函数将二进制IP转换为字符串形式std::cout 端口号: ntohs(serverAddress.sin_port) std::endl; // 使用ntohs函数将端口号从网络字节序转换为主机字节序return 0;
} 向套接字分配网络地址
bind()函数是在网络编程中常用的函数之一它用于将一个套接字socket与特定的IP地址和端口号绑定起来。以下是关于bind()函数的一些详细说明
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数解释sockfd表示要绑定的套接字描述符socket file descriptor。addr指向sockaddr结构体的指针其中包含了要绑定的IP地址和端口号信息。addrlen表示addr结构体的长度。返回值若绑定成功则返回0。若出现错误则返回-1并设置对应的错误码可以使用errno全局变量查看具体错误信息。简单示例#include iostream
#include arpa/inet.h
#include sys/socket.hint main() {int sockfd socket(AF_INET, SOCK_STREAM, 0); // 创建套接字if (sockfd -1) {std::cerr Failed to create socket. std::endl;return 1;}struct sockaddr_in serverAddr;serverAddr.sin_family AF_INET; // 使用IPv4地址族serverAddr.sin_port htons(8080); // 绑定端口号为8080serverAddr.sin_addr.s_addr INADDR_ANY; // 绑定所有可用的IP地址if (bind(sockfd, (struct sockaddr*)serverAddr, sizeof(serverAddr)) 0) {std::cerr Failed to bind socket. std::endl;return 1;}std::cout Socket bound successfully. std::endl;return 0;
}