目录
[3. bind](#3. bind)
[二、 字节序之间的转换函数](#二、 字节序之间的转换函数)
[1. inet_ntoa](#1. inet_ntoa)
[2. inet_aton](#2. inet_aton)
一、socket常用接口
1.sockaddr_in
sockaddr_in
是 Unix 和 Linux 中用于表示 IPv4 地址和端口号的结构体。当创建一个 IPv4 套接字时,这个结构体通常用于bind()
,connect()
,sendto()
,recvfrom()
等系统调用中,以指定或接收网络地址信息。
sockaddr_in
结构体的定义如下:
cppstruct sockaddr_in { short sin_family; // 地址族,对于 IPv4 通常是 AF_INET unsigned short sin_port; // 端口号,网络字节序 struct in_addr sin_addr; // IPv4 地址 char sin_zero[8]; // 未使用的填充字节,通常用零填充 };
cppstruct in_addr { uint32_t s_addr; // 32 位的 IPv4 地址,网络字节序 };
2.socket
功能
创建一个新的socket,返回一个新的socket文件描述符。
原型
cpp#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
功能
将一个套接字绑定到一个特定的地址上。
原型
cpp#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进入监听状态,等待连接。
原型
cpp#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd, int backlog);
参数
sockfd
:这是你想要设置为监听模式的套接字的文件描述符。backlog
:这是一个整数值,指定了内核应该为相应套接字排队的最大连接数返回值
成功时返回 0,失败时返回 -1 并设置全局错误变量
errno
。
5.accept
功能
当一个套接字处于监听模式(通过
listen
函数设置)时,它可以等待来自客户端的连接请求。一旦有客户端尝试连接,accept
函数就会被调用以接受这个连接,并返回一个新的套接字描述符,该描述符专门用于与这个特定客户端的通信。原型
cpp#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
功能
这个函数通常用在客户端程序中,以连接到服务器端的套接字。
原型
cpp#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 套接字在发送数据之前需要先建立连接。原型
cpp#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 套接字不需要事先建立连接就可以发送数据。原型
cpp#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
在服务器端)函数建立连接。原型
cpp#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原型
cpp#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
功能
用于关闭一个已打开的文件描述符
原型
cpp#include <unistd.h> int close(int fd);
参数
fd
或sockfd
:要关闭的socket的文件描述符。返回值
如果成功,
close
返回0
。如果失败,返回-1
并设置全局变量errno
以指示错误原因。
二、 字节序之间的转换函数
1. inet_ntoa
功能
将网络字节序的IPv4地址转换成点分十进制的字符串形式。
原型
cpp#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地址
原型
cpp#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位的无符号长整型数据(网络字节序)
原型
cpp#include <arpa/inet.h> in_addr_t inet_addr(const char *cp);
参数
cp
:指向点分十进制IPv4地址字符串的指针。返回值
成功时返回网络字节序的IPv4地址,如果输入的不是有效的表示形式则返回
INADDR_NONE
4.inet_pton
功能
将点分十进制的IP地址字符串转换为网络字节序的二进制形式。它支持IPv4和IPv6两种地址族。
原型
cpp#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地址的数字形式转换为文本格式的场景
原型
cpp#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位)数值(端口号))从主机字节序转换为网络字节序
原型
cpp#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位无符号整数从网络字节序(大端)转换为主机字节序
原型
cpp#include <arpa/inet.h> uint16_t ntohs(uint16_t netshort);
参数
netshort
是要进行转换的16位无符号整数,以网络字节序表示返回值
返回转换后的主机字节序的16位无符号整数。