目录
一、socket常用接口
1.sockaddr_in
2.socket
3. bind
4.listen
5.accept
6.connect
7.send
8.sendto
9.recv
10.recvfrom
11.close
二、 字节序之间的转换函数
1. inet_ntoa
2. inet_aton
3.inet_addr
4.inet_pton
5.inet_ntop
6.htons
7.ntohs
一、socket常用接口
1.sockaddr_in
sockaddr_in是 Unix 和 Linux 中用于表示 IPv4 地址和端口号的结构体。当创建一个 IPv4 套接字时,这个结构体通常用于bind(),connect(),sendto(),recvfrom()等系统调用中,以指定或接收网络地址信息。
sockaddr_in结构体的定义如下:struct sockaddr_in { short sin_family; // 地址族,对于 IPv4 通常是 AF_INET unsigned short sin_port; // 端口号,网络字节序 struct in_addr sin_addr; // IPv4 地址 char sin_zero[8]; // 未使用的填充字节,通常用零填充 };struct in_addr { uint32_t s_addr; // 32 位的 IPv4 地址,网络字节序 };
2.socket
功能
创建一个新的socket,返回一个新的socket文件描述符。
原型
#include <sys/types.h> #include <sys/socket.h>int socket(int domain, int type, int protocol);参数
domain:指定了协议族(也称为协议域或地址族)。常见的值有:
AF_INET:IPv4 互联网协议。AF_INET6:IPv6 互联网协议。AF_UNIX(或AF_LOCAL):本地进程间通信(Unix 域套接字)。type:指定了套接字类型。常见的值有:
SOCK_STREAM:提供有序的、可靠的、基于连接的字节流服务。它通常用于 TCP。SOCK_DGRAM:提供无连接的、不可靠的数据报服务。它通常用于 UDP。SOCK_RAW:提供原始网络访问,允许应用程序直接操作底层协议。protocol:通常设置为 0,表示选择默认的协议。在大多数情况下,对于给定的
domain和type,系统可以自动确定合适的协议。返回值
成功时返回socket文件描述符,失败时返回-1,并设置全局变量
errno以指示错误原因。
3. bind
功能
将一个套接字绑定到一个特定的地址上。
原型
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数
sockfd:这是通过
socket()函数创建的套接字文件描述符。addr:这是一个指向
sockaddr结构体的指针,该结构体包含了要绑定的地址信息。这个地址可以是 IP 地址和端口号的组合,或者对于 Unix 域套接字,它可能是一个文件路径。addrlen:这是
addr参数指向的地址结构体的长度。这允许函数知道addr指向的结构的类型(因为sockaddr是一个通用结构,有不同的变体,如sockaddr_in用于 IPv4,sockaddr_in6用于 IPv6,sockaddr_un用于 Unix 域套接字)。返回值
- 如果绑定成功,函数返回 0。
- 如果绑定失败,函数返回 -1,并设置全局变量
errno以指示错误原因。
4.listen
功能
使socket进入监听状态,等待连接。
原型
#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd, int backlog);参数
sockfd:这是你想要设置为监听模式的套接字的文件描述符。backlog:这是一个整数值,指定了内核应该为相应套接字排队的最大连接数返回值
成功时返回 0,失败时返回 -1 并设置全局错误变量
errno。
5.accept
功能
当一个套接字处于监听模式(通过
listen函数设置)时,它可以等待来自客户端的连接请求。一旦有客户端尝试连接,accept函数就会被调用以接受这个连接,并返回一个新的套接字描述符,该描述符专门用于与这个特定客户端的通信。原型
#include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);参数
sockfd:这是监听套接字(即调用过listen的套接字)的文件描述符。addr:这是一个指向sockaddr结构的指针,该结构用于存储客户端的地址信息。如果不需要客户端的地址信息,这个参数可以设置为NULL。addrlen:这是一个指向socklen_t类型变量的指针,该变量在调用accept之前应该设置为addr结构的大小。当accept返回时,它将包含实际存储在addr中的地址信息的大小。返回值
成功时返回一个非负整数,这个整数是新套接字的文件描述符,用于与客户端通信。如果出错,则返回
-1并设置全局错误变量errno。
6.connect
功能
这个函数通常用在客户端程序中,以连接到服务器端的套接字。
原型
#include <sys/types.h> #include <sys/socket.h> int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数
sockfd:这是客户端想要连接的套接字的文件描述符。这个套接字之前通常通过socket函数创建。addr:这是一个指向sockaddr结构体的指针,该结构体包含了目标服务器的地址和端口信息。addrlen:这是addr结构体的大小,以字节为单位。返回值
成功时返回 0,表示连接已建立。如果连接失败,它将返回 -1 并设置全局错误变量
errno以指示错误原因。
7.send
功能
send函数用于在已连接的套接字上发送数据。它通常用于 TCP 套接字,因为 TCP 套接字在发送数据之前需要先建立连接。原型
#include <sys/types.h> #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags);参数
sockfd:这是已连接套接字的文件描述符。这个套接字之前通常通过socket函数创建,并通过connect函数与远程主机建立了连接。buf:这是一个指向要发送数据的缓冲区的指针。这个缓冲区包含了要发送的数据。len:这是要发送数据的字节数。它指定了从buf指向的缓冲区中要发送的字节数。flags:这是一组标志,用于修改发送操作的行为。这些标志可以影响发送操作的方式,例如是否应该进行非阻塞发送等。常见的标志包括MSG_DONTWAIT(非阻塞发送)和MSG_OOB(发送带外数据)。一般设为0,当flags设置为0时,send函数会以阻塞模式尝试发送整个请求的数据块,并等待直到数据被成功发送或发生错误。返回值
成功时返回发送的字节数,如果出错则返回 -1 并设置全局错误变量
errno。
8.sendto
功能
sendto函数用于在无连接套接字上发送数据。它通常用于 UDP 套接字,因为 UDP 套接字不需要事先建立连接就可以发送数据。原型
#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);参数
ockfd:这是无连接套接字的文件描述符。buf和len:与send函数中的参数相同,分别指向要发送的数据缓冲区和数据长度。flags:与send函数中的标志参数相同。dest_addr和addrlen:这两个参数指定了数据的目标地址和地址长度。对于 UDP 套接字,这通常是接收方的 IP 地址和端口号。返回值
成功时返回发送的字节数,如果出错则返回 -1 并设置全局错误变量
errno。
9.recv
功能
recv函数用于从已连接的套接字接收数据的函数。它通常与send函数配对使用,特别是在 TCP 套接字通信中。TCP 是一种面向连接(面向字节流)的协议,因此在使用recv之前,通常需要先通过socket和connect(或accept在服务器端)函数建立连接。原型
#include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags);参数
sockfd:这是已连接套接字的文件描述符。这个套接字应该是一个已经建立连接的 TCP 套接字。buf:这是一个指向接收数据缓冲区的指针。这个缓冲区用于存储从套接字接收到的数据。len:这是要接收数据的最大字节数。它指定了buf指向的缓冲区能够容纳的最大字节数。flags:这是一组标志,用于修改接收操作的行为。虽然对于recv函数来说,这些标志的使用不像send函数那么频繁,但它们仍然可以用于一些特殊用途,例如是否应该进行峰值接收等。一般设为0,当flags设置为 0 时,recv会以阻塞模式、顺序接收数据,并移除已读取的数据。这是大多数应用程序在处理 TCP 套接字接收数据时的期望行为。如果你需要改变这些默认行为(例如,使用非阻塞模式或只查看数据而不移除),你应该使用相应的flags值。返回值
成功时返回接收的字节数,失败时返回-1, 并设置全局错误变量
errno。如果连接已关闭且没有数据可接收,则返回0。
10.recvfrom
功能
recvfrom函数用于从指定的套接字接收数据,并可以获取发送方的地址信息。这个函数通常用于无连接的套接字类型,如 UDP,但也可以用于连接模式的套接字,如 TCP原型
#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);参数
int sockfd:要接收数据的套接字的文件描述符。void *buf:指向一个缓冲区的指针,该缓冲区用于存储接收到的数据。size_t len:指定buf缓冲区的大小,即最多可以接收的字节数。int flags:指定接收操作的标志。一般设为0,表示进行默认是接收操作。struct sockaddr *src_addr:指向一个sockaddr结构体的指针,用于存储发送方的地址信息。如果此参数为 NULL,则不获取发送方地址。socklen_t *addrlen:指向一个整数变量的指针,用于存储src_addr结构体的实际大小。在调用recvfrom之前,应该将此变量设置为src_addr结构体的大小(通常使用sizeof(struct sockaddr))。如果src_addr为 NULL,则此参数也应为 NULL。返回值
成功时返回接收的字节数,失败时返回-1, 并设置全局错误变量
errno。如果连接已关闭且没有数据可接收,则返回0。
11.close
功能
用于关闭一个已打开的文件描述符
原型
#include <unistd.h> int close(int fd);参数
fd或sockfd:要关闭的socket的文件描述符。返回值
如果成功,
close返回0。如果失败,返回-1并设置全局变量errno以指示错误原因。
二、 字节序之间的转换函数
1. inet_ntoa
功能
将网络字节序的IPv4地址转换成点分十进制的字符串形式。
原型
#include <arpa/inet.h> char *inet_ntoa(struct in_addr inaddr);参数
inaddr:一个struct in_addr结构体,包含网络字节序的IPv4地址。返回值
返回指向一个静态存储的点分十进制字符串的指针。如果传入的不是有效的IPv4地址,则结果不可预测。
2. inet_aton
功能
将一个点分十进制的IP地址字符串(例如"127.0.0.1")转换为一个32位的网络字节序的IP地址
原型
#include <arpa/inet.h> int inet_aton(const char *cp, struct in_addr *inp);参数
cp是一个指向以点分十进制表示的IP地址字符串的指针。inp是一个指向struct in_addr的指针,该结构体用于存储转换后的网络字节序的IP地址。返回值
如果转换成功,
inet_aton函数返回非零值;如果输入地址不正确(例如,不是有效的IP地址),则返回零。此外,值得注意的是,使用inet_aton函数并没有错误码存放在errno中,所以其返回值通常被直接用来判断转换是否成功。
3.inet_addr
功能
一个点分十进制的IPv4地址转换为一个32位的无符号长整型数据(网络字节序)
原型
#include <arpa/inet.h> in_addr_t inet_addr(const char *cp);参数
cp:指向点分十进制IPv4地址字符串的指针。返回值
成功时返回网络字节序的IPv4地址,如果输入的不是有效的表示形式则返回
INADDR_NONE
4.inet_pton
功能
将点分十进制的IP地址字符串转换为网络字节序的二进制形式。它支持IPv4和IPv6两种地址族。
原型
#include <arpa/inet.h> int inet_pton(int af, const char *src, void *dst);参数
af:指定地址族,AF_INET指定 IPv4 地址,AF_INET6指定 IPv6 地址。src:指向要转换的字符串地址的指针。dst:指向存放网络字节序的二进制结果的地址的指针。返回值
- 如果成功将地址字符串转换为网络字节序整数,
inet_pton会返回 1。- 如果输入的地址字符串无效,它会返回 0。
- 如果发生错误,它会返回 -1。
5.inet_ntop
功能
它的主要作用是将网络字节序(大端序)的IPv4或IPv6地址转换成人类可读的字符串形式。这个函数特别适用于需要将IP地址的数字形式转换为文本格式的场景
原型
#include <arpa/inet.h> const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);参数
af:地址族,指定了要转换的地址类型。可以是AF_INET(表示IPv4)或AF_INET6(表示IPv6)。src:指向要转换的二进制地址的指针。这个地址应该是网络字节序的。dst:指向存储转换后的字符串的缓冲区的指针。size:dst缓冲区的大小。这用于避免缓冲区溢出。返回值
- 如果转换成功,
inet_ntop()函数返回一个指向dst的指针,该指针指向转换后的字符串地址。- 如果发生错误(比如缓冲区太小无法存储转换后的字符串),则返回值为
NULL,并设置全局错误号errno。
6.htons
功能
将无符号短整形(16位)数值(端口号))从主机字节序转换为网络字节序
原型
#include <arpa/inet.h> uint16_t htons(uint16_t hostshort);参数
hostshort参数是一个以主机字节序存储的无符号短整形数值返回值
返回转换后的网络字节序的无符号短整形数值。
注意
htons函数仅处理16位数值的转换,对于32位数值的转换,应使用htonl(host to network long)函数。同时,对于从网络接收到的数据,需要使用ntohs(network to host short)函数进行相反的转换,即从网络字节序转换回主机字节序。
7.ntohs
功能
用于将16位无符号整数从网络字节序(大端)转换为主机字节序
原型
#include <arpa/inet.h> uint16_t ntohs(uint16_t netshort);参数
netshort是要进行转换的16位无符号整数,以网络字节序表示返回值
返回转换后的主机字节序的16位无符号整数。