北京做手机网站的公司,套模板网站价格表,深圳门户网站建设专业,制作物流网站目录
一#xff0c;socket编程的相关说明
1-1#xff0c;sockaddr结构体
1-2#xff0c;Socket API
二#xff0c;基于Udp协议的简单通信 一#xff0c;socket编程的相关说明 Socket编程是一种网络通信编程技术#xff0c;它允许两个或多个程序在网络上相互通信…目录
一socket编程的相关说明
1-1sockaddr结构体
1-2Socket API
二基于Udp协议的简单通信 一socket编程的相关说明 Socket编程是一种网络通信编程技术它允许两个或多个程序在网络上相互通信无论这些程序是否运行在同一台计算机上。 在Socket编程中每个网络通信端点都被称为一个套接字封装了底层的网络协议如TCP/IP的细节。这个套接字支持不同的传输协议可以看作是两个程序之间打开的一个通信通道通过这个通道程序可以在网络上进行数据的传输。 不同主机在网络上进行数据传输时需要拿到拿到对方的端口号标识主机的应用程序或网络服务在网络通信中确保将数据包交给哪个主机上的应用程序来处理和IP地址互联网上每一台计算机的地址在网络通信中用于标识主机的位置。IP地址用于寻找指定机器找到指定机器后就需要端口号来找到指定机器下的指定服务或程序。 注意服务端通常不会给予特定的IP地址。首先如果指定服务端的IP地址那么服务端程序只能在特定的网络环境中运行要是网络环境发生变化例如服务器迁移到新的IP地址则需要重新编译和部署程序。其次在很多的场景中服务端程序不仅需要部署在多个服务器上还需要在不同的机器和网络环境中运行具有多个网络接口它的IP地址也可能会动态变化。这时若多个客户端连接到一个服务端上指定特定的IP地址会导致连接出错等问题。
1-1sockaddr结构体 Socket编程中struct sockaddr 结构体是常用的类型操作该结构体是用于描述套接字地址的通用结构体并指定或返回网络地址信息是一个通用的地址结构体它通常出现在套接字函数的参数中在网络编程中广泛使用。运用时由于网络地址协议格式各有不同所以该结构体通常会被更具体的地址结构体如 struct sockaddr_in 或 struct sockaddr_in6所替代这些结构体提供了更详细的地址信息需要时一般都是通过指针将sockaddr进行强制转换具体使用请看后面代码。 struct sockaddr_in是基于IPv4编程的网络环境中使用的数据结构。这个结构里主要有三部分信息地址类型、端口号、IP地址。 struct sockaddr_in { 地址族对于 IPv4 来说是 AF_INET 注意地址族是将不同的网络层协议如IPv4、IPv6等进行分类的一种方式。它允许网 络设备根据地址族来识别和处理不同协议的数据包指定源字符串的地址类型。一般用 于区分IPv4和IPv6。 sa_family_t sin_family; 端口号由于端口号也需要经过网络传送网络通信时需要拿到对方的端口号进行通 信所以传递网络前需要使用 htons()函数将其转换为网络字节序 uint16_t sin_port; 包含一个 32 位IPv4 地址的结构体 struct in_addr sin_addr; 用来将结构大小填充到与 struct sockaddr 相同的大小通常被设置为零。 char sin_zero[8]; }; typedef uint32_t in_addr_t; struct in_addr { in_addr_t s_addr; 一个 32 位的IPv4 地址 }; 注意 1网络数据传输时IP地址也需要经过网络传输所以这里需要把点分十进制的IP地址字符串类型转换成网络字节序 2inet_addr()用来表示一个IPv4的IP地址32位的整数。通常使用inet_pton()或 inet_addr()函数来将点分十进制的 IPv4 地址字符串转换为4字节的网络字节序大端序 3inet_pton() 和 inet_addr()虽然都是用于将IP地址字符串形式转换为网络字节序的二进制形式但是inet_pton() 不仅支持IPv4还支持 IPv6 地址的转换除此外inet_pton()通常还是线程安全的inet_addr() 可能不是线程安全的。inet_pton() 是较新的函数提供了更广泛的功能和更好的错误处理但是该函数运用起来比较复杂。 4当网络IP地址传送到主机上时需要用特定的函数比如inet_pton()将其转换成点分十进制的字符串形式。 inet_addr 格式in_addr_t inet_addr(const char *cp); 参数cp指向一个以空字符结尾的字符串该字符串表示一个点分十进制格式的IPv4 地址例如192.168.1.1。 返回值成功时返回该IP地址的网络字节序表示一个in_addr_t类型的值。如果 输入字符串不是有效的IPv4地址函数返回INADDR_NONE通常是-1在 netinet/in.h头文件中定义。 inet_pton 格式int inet_pton(int af, const char *src, void *dst); 参数 af地址族。一般是AF_INET或AF_INET6 src指向一个以空字符结尾的字符串该字符串表示一个点分十进制格式的IPv4 地址AF_INET或十六进制格式的IPv6地址AF_INET6 dst指向一个缓冲区该缓冲区存储转换后的网络字节序地址 返回值 成功时返回1。 如果输入字符串不是有效的地址格式返回0。 如果发生系统级错误例如参数不合法返回-1。 inet_ntoa 功能将网络字节序的二进制IP地址转换为点分十进制的IP地址字符串 格式char *inet_ntoa(struct in_addr in); 参数in表示一个32位的IPv4地址的结构体即需要转换网络字节序的二进制IP地址 返回值成功时返回一个表示点分十进制的IP地址的字符串失败时返回NULL。 1-2Socket API socket API是一层抽象的网络编程接口其中API代表应用程序编程接口。在socket编程中API提供了一系列用于网络通信的函数和接口。这些API函数封装了底层网络通信的复杂性为开发者提供了简单而强大的接口。通过API应用程序可以调用操作系统或其他软件服务提供的函数和程序以实现特定的功能或操作。常见的socket API包括 1socket。用于创建一个新的套接字相关说明如下 头文件 #include sys/types.h #include sys/socket.h 格式 int socket(int domain, int type, int protocol); 参数说明 domain指定通信时使用的协议族。常用的协议族有 AF_INETIPv4的协议族。IPv4地址类型定义在常数AF_INET中AF_INET6IPv6的协议族。IPv6地址类型定义在常数AF_INET6中AF_UNIX或AF_LOCAL本地通信协议族通常用于同一台机器上的进程间通信。type指定套接字类型。常用的套接字类型有 SOCK_STREAM流式套接字用于TCP连接。SOCK_DGRAM数据报套接字用于UDP连接。SOCK_RAW原始套接字允许对IP层及以下的数据进行直接访问和操作。protocol通常设置为0表示自动选择该domain和type组合下的默认协议。特殊情况下会设置特定的协议这里先不考虑。 返回值 成功时该函数返回一个非负数的套接字描述符也可以理解为文件描述符因为Linux一切皆文件该描述符在后续的网络操作中用于标识该套接字失败时返回-1。 2bind。函数用于将一个套接字与一个特定的地址通常是IP地址和端口号即sockaddr结构体关联起来。在服务器程序中这通常是第一步因为服务器需要在一个特定的端口上监听来自客户端的连接请求即绑定端口号。 注意在计算机网络编程中bind 函数主要用于服务器端而不是客户端。服务端是确定的需要绑定到一个特定的 IP 地址和端口号需要在应用程序启动时绑定以便客户端能够连接到它。客户端一般可以打开多个服务比如打开淘宝、百度、抖音等若是使用bind 函数连接固定的端口号可能会导致不同的网络服务使用到同一个端口号导致服务冲突因此客户端通常是在首次发送数据的时候由操作系统动态分配一个临时的端口号来进行通信不需要使用专门函数绑定到特定的 IP 地址和端口号。 头文件 #include sys/types.h #include sys/socket.h 格式 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数说明 sockfd要绑定套接字的文件描述符。addr指向一个 sockaddr 结构的指针该结构包含了要绑定的地址和端口信息。在实际使用中通常会使用 sockaddr_in 结构基于IPv4地址或 sockaddr_in6 结构基于IPv6地址。addrlenaddr参数所指向的地址结构的长度。 返回值 成功时返回0失败时返回-1。 3listen。该函数用于将套接字设置为监听状态以接受来自客户端的连接请求。这个函数通常在服务器程序中调用在调用 bind 函数时将套接字与特定地址IP地址和端口号关联之后使用。 头文件 #include sys/types.h #include sys/socket.h 格式 int listen(int sockfd, int backlog); 参数说明 sockfd要监听套接字的文件描述符。backlog指定系统内核应为相应套接字排队的最大连接数。一般设置为 SOMAXCONN即使用系统定义的最大值。 返回值 成功时返回0失败时返回-1。 4recvfrom。该函数用于从套接字中接收数据默认情况下若 recvfrom 在没有数据可读的情况下被调用它将会阻塞等待。该函数特别是在处理无连接协议如 UDP时经常使用。 这里先说明下 socklen_t 类型它是一个无符号整数类型其长度至少为32位具体大小可能因操作系统和平台而异用于指定套接字地址结构的大小。 头文件 #include sys/types.h #include sys/socket.h 格式 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); 注意 ssize_t是一个平台相关的类型在32位机器上ssize_t通常等同于int类型在64位机器上它通常等同于long int类型。 参数说明 sockfd套接字文件描述符表示接收数据的套接字。 buf指向接收数据缓冲区的指针。 len指定缓冲区 buf 的大小即最多可以接收的数据字节数。 flags通常设置为 0可以是某些特性功能的字段这里不做说明。 src_addr指向 sockaddr 结构的指针用于存储发送方地址信息。如果不需要此信息可以设置为 NULL。 addrlen指向一个在调用时包含 src_addr 结构大小的指针在返回时包含实际写入 src_addr 的大小。如果 src_addr 是 NULL则 addrlen 也应该是 NULL。 返回值 成功时返回接收到的字节数如果连接已正常关闭则返回 0失败时返回 -1。 5sendto。该函数主要用于发送数据到指定的套接字是网络编程中发送数据的函数之一。 头文件 #include sys/types.h #include sys/socket.h 格式 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 注意 ssize_t是一个平台相关的类型在32位机器上ssize_t通常等同于int类型在64位机器上它通常等同于long int类型。参数说明 sockfd套接字文件描述符表示要发送数据的套接字。buf指向包含要发送数据的缓冲区的指针。len要发送的数据的长度以字节为单位。flags通常设置为 0可以是某些特性功能的字段这里不做说明。dest_addr指向 sockaddr 结构体的指针表示数据发送的目标地址信息。对于 TCP 连接这个参数通常不需要因为连接已经建立了目标地址但对于 UDP这个参数是必须的。addrlendest_addr 结构体的大小。 返回值 成功时返回发送的字节数失败时返回 -1。 socket API还有很多我们暂时先了解这些后面遇到需要时会进行说明。 二基于Udp协议的简单通信 服务器的IP地址一般不指定因此下面程序实现时我们将服务端的IP地址设为0表示接收任意IP地址这时只有端口号标识其服务端。 服务端的端口号我们使用输入的环境变量的方式来确定形式为【可执行文件】【十六位的端口号】。其它形式的输入全部出错。这时客户端只要连接到指定输入服务器的端口号即可完成远程网络连接进行通信。通过服务端我们可查看客户端的IP和端口号下面代码演示会看到。 注意云服务器的端口号默认都是禁止访问的若要使用云服务器实现通信首先需要自己开放云服务器的端口。至于如何开放云服务器的端口号请看此文章云服务器端口开放 客户端创建套接字时不用使用bind函数进行绑定系统会自动绑定。 客户端运行的方式这里使用【可执行文件】【连接服务器的IP地址】【十六位的端口号】形式其它形式的输入全部错误。 程序总代码请在此链接下观看UdpSocket代码程序