简介
- <sys/socket.h>头文件 笔记
linux <sys/socket.h>是什么
<sys/socket.h>
是一个 C/C++ 语言中的头文件,通常用于在 Linux 系统上进行网络编程。该头文件包含了一系列用于创建、操作网络套接字(socket)的函数、结构体和宏定义。
套接字是网络通信的基础,它允许进程通过网络进行通信。<sys/socket.h>
中定义了创建套接字、绑定地址、监听连接、接受连接等操作所需的函数和相关的常量、数据结构。这些函数和常量允许开发者在 Linux 系统上编写网络应用程序,实现各种网络通信,如 TCP、UDP、IPv4、IPv6 等。
一些常用的函数包括 socket()
(创建套接字)、bind()
(绑定套接字地址)、listen()
(监听连接)、accept()
(接受连接请求)、connect()
(建立连接)、send()
和 recv()
(发送和接收数据)等。
这个头文件以及相关的系统调用和函数提供了程序员在 Linux 平台上进行网络编程的基础,使得开发者能够编写网络应用程序来实现数据通信和网络服务。
linux <sys/socket.h>详解
<sys/socket.h>
是 Linux 系统中用于网络编程的头文件之一,它包含了一系列用于处理套接字(socket)的系统调用、结构体和宏定义。
套接字是一种抽象的通信端点,允许不同计算机之间进行数据通信。<sys/socket.h>
提供了创建、配置和操作套接字的函数和常量,使得开发者能够进行网络通信。以下是该头文件中常用的一些函数、数据结构和宏定义:
数据结构:
struct sockaddr
:用于表示通用的套接字地址信息。struct sockaddr_in
:用于表示 IPv4 的套接字地址信息。struct sockaddr_in6
:用于表示 IPv6 的套接字地址信息。struct sockaddr_storage
:用于存储任意类型套接字地址的结构体。
函数:
socket()
:创建一个新的套接字,返回一个文件描述符。bind()
:将一个套接字绑定到特定的地址和端口。listen()
:开始监听传入的连接请求。accept()
:接受传入的连接请求并返回新的套接字。connect()
:建立与远程套接字的连接。send()
和recv()
:发送和接收数据。close()
:关闭套接字连接。
常量和宏定义:
- 套接字类型:
SOCK_STREAM
(流套接字,提供面向连接的、可靠的字节流服务,如 TCP)、SOCK_DGRAM
(数据报套接字,提供无连接的数据传输,如 UDP)等。 - 地址族:
AF_INET
(IPv4 地址族)、AF_INET6
(IPv6 地址族)等。 - 套接字选项:如
SO_REUSEADDR
(允许地址重用)、SO_KEEPALIVE
(启用保活机制)等。
使用 <sys/socket.h>
中提供的函数和常量,开发者可以实现各种网络应用,包括客户端-服务器模型、网络通信、数据传输等。这些函数和常量为 Linux 下的网络编程提供了基础设施。
linux <sys/socket.h> struct sockaddr详解
在 Linux 的 <sys/socket.h>
头文件中,struct sockaddr
是用于表示通用的套接字地址信息的结构体。它是一个通用的地址结构,用于在网络编程中传递和存储各种类型的套接字地址信息,无论是 IPv4、IPv6 还是其他协议族的地址信息。
struct sockaddr
的定义如下:
1
2
3
4
struct sockaddr {
unsigned short sa_family; // 地址族,例如 AF_INET、AF_INET6
char sa_data[14]; // 实际的地址信息,大小取决于不同的协议族
};
这个结构体的主要成员有:
-
sa_family
:表示地址族(address family),用于指示地址的类型,例如AF_INET
表示 IPv4 地址族,AF_INET6
表示 IPv6 地址族。这个字段的大小为 2 个字节(unsigned short
)。 -
sa_data
:这是一个包含实际地址信息的字符数组,大小为 14 字节。在实际使用中,这个字段会被强制转换为不同类型的结构体,以便于存储特定地址族的信息。例如,对于 IPv4 地址族 (AF_INET
),会将struct sockaddr
转换为struct sockaddr_in
,而对于 IPv6 地址族 (AF_INET6
),会转换为struct sockaddr_in6
。
由于 struct sockaddr
是一个通用的结构体,它通常与类型转换结合使用,以适应不同的地址族和套接字操作。例如,在使用时,你可能会使用类型转换来将 struct sockaddr
转换为 struct sockaddr_in
或 struct sockaddr_in6
,这样就可以操作 IPv4 或 IPv6 地址信息。
网络编程中经常使用的函数,如 bind()
、connect()
、accept()
等,通常需要 struct sockaddr
类型的地址作为参数,以指定套接字的地址信息。在这些函数中,struct sockaddr
以及其不同的转换类型用于存储和传递相关的地址信息。
linux <sys/socket.h> struct sockaddr_in详解
在 Linux 的 <sys/socket.h>
头文件中,struct sockaddr_in
是用于表示 IPv4 套接字地址信息的结构体。它是对通用的 struct sockaddr
结构的扩展,专门用于存储和处理 IPv4 地址信息。
struct sockaddr_in
的定义如下:
1
2
3
4
5
6
struct sockaddr_in {
sa_family_t sin_family; // 地址族,一般为 AF_INET
in_port_t sin_port; // 16 位端口号
struct in_addr sin_addr; // IPv4 地址
unsigned char sin_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(in_port_t) - sizeof(struct in_addr)]; // 用于填充使结构体大小与 sockaddr 一致
};
这个结构体的主要成员包括:
-
sin_family
:与通用的struct sockaddr
相同,表示地址族,通常设置为AF_INET
表示 IPv4 地址族。 -
sin_port
:一个 16 位的整数,表示端口号。在网络编程中,端口号用于标识进程在主机上运行的服务。 -
sin_addr
:一个struct in_addr
类型的结构体成员,用于存储 IPv4 地址信息。 -
sin_zero
:用于填充,使得struct sockaddr_in
的大小与struct sockaddr
保持一致。这样做是为了与旧版代码兼容,新的套接字地址结构体struct sockaddr_in
虽然有自己的大小,但是要与通用的struct sockaddr
大小一致以便于类型转换和处理。
在实际使用中,struct sockaddr_in
结构体通常与其他函数和数据类型一起使用,例如 bind()
、connect()
和 accept()
等函数需要将 struct sockaddr_in
类型的地址信息作为参数传递。
这个结构体和相关的函数使得开发者可以在 Linux 系统上进行 IPv4 网络编程,并能够方便地处理 IPv4 地址和端口信息。
linux <sys/socket.h> struct sockaddr_in6详解
在 Linux 的 <sys/socket.h>
头文件中,struct sockaddr_in6
是用于表示 IPv6 套接字地址信息的结构体。与 struct sockaddr_in
类似,struct sockaddr_in6
是对通用的 struct sockaddr
结构的扩展,专门用于存储和处理 IPv6 地址信息。
struct sockaddr_in6
的定义如下:
1
2
3
4
5
6
7
struct sockaddr_in6 {
sa_family_t sin6_family; // 地址族,一般为 AF_INET6
in_port_t sin6_port; // 16 位端口号
uint32_t sin6_flowinfo; // 流标识和流级别
struct in6_addr sin6_addr; // IPv6 地址
uint32_t sin6_scope_id; // 用于设置接口的标识符
};
这个结构体的主要成员包括:
-
sin6_family
:与通用的struct sockaddr
相同,表示地址族,通常设置为AF_INET6
表示 IPv6 地址族。 -
sin6_port
:一个 16 位的整数,表示端口号。在网络编程中,端口号用于标识进程在主机上运行的服务。 -
sin6_flowinfo
:用于指定数据包的流信息。 -
sin6_addr
:一个struct in6_addr
类型的结构体成员,用于存储 IPv6 地址信息。 -
sin6_scope_id
:用于设置接口的标识符,以标识某个特定接口。
与 struct sockaddr_in
类似,struct sockaddr_in6
结构体也会用于与各种函数和数据类型一起使用,例如 bind()
、connect()
和 accept()
等函数需要将 struct sockaddr_in6
类型的地址信息作为参数传递。
这个结构体和相关的函数使得开发者可以在 Linux 系统上进行 IPv6 网络编程,并能够方便地处理 IPv6 地址和端口信息。
linux <sys/socket.h> struct sockaddr_storage详解
在 Linux 的 <sys/socket.h>
头文件中,struct sockaddr_storage
是一个通用的、足够大以容纳任何套接字地址结构的结构体。它被设计为一个泛型的套接字地址结构,可用于存储各种不同类型的套接字地址信息,包括 IPv4、IPv6 或其他协议族的地址信息。
struct sockaddr_storage
的定义如下:
1
2
3
4
5
6
struct sockaddr_storage {
sa_family_t ss_family; // 地址族,用于指示地址的类型
char __ss_pad1[_SS_PAD1SIZE]; // 结构体填充,确保内存对齐
int64_t __ss_align; // 结构体对齐
char __ss_pad2[_SS_PAD2SIZE]; // 结构体填充,确保内存对齐
};
其中,_SS_PAD1SIZE
和 _SS_PAD2SIZE
是为了内存对齐而填充的大小。
struct sockaddr_storage
结构体最主要的成员是 ss_family
,用于指示实际地址结构的类型。根据 ss_family
的值,可以进行类型转换,将 struct sockaddr_storage
转换为相应的地址结构(例如 struct sockaddr_in
或 struct sockaddr_in6
),以便于处理特定类型的套接字地址。
struct sockaddr_storage
通常用于网络编程中,当你需要处理不同类型的套接字地址时,可以将不同的地址类型都转换为 struct sockaddr_storage
,以便于统一地进行存储和传递。
这个结构体的设计使得它成为一个通用的容器,可以存储不同类型的套接字地址,为网络编程提供了一定的灵活性和扩展性。
linux <sys/socket.h> setsockopt()详解
setsockopt()
是 Linux 中 <sys/socket.h>
头文件中定义的函数,用于设置 socket 的选项参数。它允许对打开的 socket 进行配置和控制,以适应特定的网络通信需求。
函数原型
1
2
3
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
sockfd
是要设置选项的 socket 文件描述符。level
是选项的协议级别,通常是SOL_SOCKET
(表示通用 socket 选项),也可以是特定协议的级别,如IPPROTO_TCP
或IPPROTO_IP
。optname
是要设置的选项名称。optval
是一个指向存放选项值的缓冲区的指针。optlen
是选项值的长度。
返回值
- 如果设置选项成功,返回值为 0。
- 如果失败,返回值为 -1,并设置
errno
表示错误的原因。
使用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置 socket 选项,例如设置 SO_REUSEADDR 选项
int optval = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// 进行其他操作
close(sockfd); // 关闭 socket
return 0;
}
作用
setsockopt()
函数允许在创建 socket 后,通过设置选项对 socket 进行配置,如修改 socket 的属性、调整 socket 的行为等。- 例如,可以通过设置
SO_REUSEADDR
选项来允许地址重用,允许多个 socket 绑定到相同的地址和端口。 - 还可以使用其他选项来调整缓冲区大小、设置超时、启用或禁用协议特性等。
总之,setsockopt()
是一个用于设置 socket 选项的函数,可以根据需要配置和控制 socket 的行为,以满足特定的网络通信需求。
linux <sys/socket.h> socket详解
在 Linux 中,<sys/socket.h>
头文件提供了在网络编程中使用的套接字(socket)相关的函数和宏定义。其中最重要的函数之一就是 socket()
。
socket()
函数用于创建一个新的套接字,并返回一个文件描述符,该文件描述符用于后续对该套接字的操作,比如发送和接收数据、连接等。
函数原型如下:
1
int socket(int domain, int type, int protocol);
参数解释:
domain
:指定套接字的协议族(例如AF_INET
表示 IPv4,AF_INET6
表示 IPv6 等)。type
:指定套接字的类型(例如SOCK_STREAM
表示流套接字,提供可靠的、面向连接的服务,如 TCP;SOCK_DGRAM
表示数据报套接字,提供无连接的服务,如 UDP)。protocol
:指定协议,通常设置为 0,表示使用domain
和type
参数默认的协议。
示例用法:
1
2
3
4
5
6
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 对新创建的套接字进行后续操作,比如绑定地址、监听连接、接受连接等
通过 socket()
函数,你可以在 Linux 系统上创建不同类型的套接字,根据指定的协议族、类型和协议进行网络编程。接下来,可以使用返回的文件描述符对套接字进行各种操作,比如绑定地址、建立连接、发送和接收数据等。
linux <sys/socket.h> bind()详解
在 Linux 的 <sys/socket.h>
头文件中,bind()
函数用于将一个套接字(socket)与一个特定的地址(IP 地址和端口号)绑定在一起。这个函数主要用于服务器端程序,在服务器启动时指定它所在的 IP 地址和端口号,以便客户端能够连接到该地址。
函数原型如下:
1
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数解释:
sockfd
:套接字文件描述符,通过socket()
函数创建的套接字描述符。addr
:指向struct sockaddr
结构体的指针,包含要绑定的地址信息。addrlen
:addr
结构体的长度。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT); // 设置端口号
server_addr.sin_addr.s_addr = INADDR_ANY; // 将套接字绑定到任何可用的地址
int bind_status = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bind_status < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
在上述示例中,bind()
函数将创建的套接字 sockfd
与 struct sockaddr_in
结构体中指定的 IP 地址和端口号绑定在一起。对于服务器程序,bind()
通常在 socket()
之后立即调用,以指定服务器将要监听的地址和端口。
绑定成功后,服务器可以使用该地址接收来自客户端的连接请求。如果绑定失败,bind()
将返回一个负值,并且可以通过 perror()
函数打印错误信息。
需要注意的是,在使用 bind()
函数之前,确保指定的端口号没有被其他进程占用,并且有足够的权限来绑定该地址。
linux <sys/socket.h> listen()详解
在 Linux 的 <sys/socket.h>
头文件中,listen()
函数用于将指定的套接字(socket)转换为被动监听套接字,即将套接字用于接受连接请求,并指定服务器套接字可以排队等待的最大连接请求数量。
函数原型如下:
1
int listen(int sockfd, int backlog);
参数解释:
sockfd
:套接字文件描述符,通过socket()
函数创建的套接字描述符。backlog
:指定等待连接队列的最大长度,即允许排队等待的最大连接请求数量。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
// 填充 server_addr 结构体...
int bind_status = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bind_status < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
int listen_status = listen(sockfd, 5); // 允许最多 5 个连接请求排队等待处理
if (listen_status < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
在上述示例中,listen()
函数将创建的套接字 sockfd
转换为一个被动监听套接字,允许最多 5 个连接请求排队等待处理。这表示如果有更多的连接请求到达服务器但尚未被处理,它们将被拒绝或者等待,直到服务器处理当前排队的连接请求。
listen()
函数通常在调用 bind()
函数之后,并且在调用 accept()
函数之前调用。当套接字处于监听状态时,服务器可以使用 accept()
函数接受连接请求并创建新的套接字用于与客户端通信。
linux <sys/socket.h> accept()详解
在 Linux 的 <sys/socket.h>
头文件中,accept()
函数用于从被动监听套接字(listening socket)接受客户端的连接请求,创建一个新的连接套接字,并返回一个新的文件描述符,通过该文件描述符可以与客户端进行通信。
函数原型如下:
1
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数解释:
sockfd
:被监听的套接字文件描述符,通过socket()
函数创建并经过bind()
和listen()
的设置。addr
:用于存储客户端地址信息的结构体指针,当成功建立连接时,此结构体将填充为客户端的地址信息。addrlen
:addr
结构体的长度指针,接受的客户端地址信息的长度。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
// 填充 server_addr 结构体...
int bind_status = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bind_status < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
int listen_status = listen(sockfd, 5);
if (listen_status < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in client_addr;
socklen_t client_addrlen = sizeof(client_addr);
int new_socket = accept(sockfd, (struct sockaddr *)&client_addr, &client_addrlen);
if (new_socket < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
在上述示例中,accept()
函数从被监听套接字 sockfd
中接受连接请求,并创建了一个新的套接字 new_socket
,用于与客户端进行通信。同时,accept()
将填充 client_addr
结构体,包含客户端的地址信息。
accept()
函数在服务器端通常用于循环中,每次调用 accept()
都会接受一个新的连接请求,返回一个新的套接字用于与新客户端进行通信。这样服务器可以同时处理多个客户端的连接请求。
linux <sys/socket.h> connect()详解
在 Linux 的 <sys/socket.h>
头文件中,connect()
函数用于建立与远程服务器的连接。它被用于客户端程序,用于向服务器发起连接请求。
函数原型如下:
1
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数解释:
sockfd
:客户端套接字文件描述符,通过socket()
函数创建的套接字描述符。addr
:指向struct sockaddr
结构体的指针,包含要连接的目标地址信息。addrlen
:addr
结构体的长度。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
// 填充 server_addr 结构体...
int connect_status = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (connect_status < 0) {
perror("connection failed");
exit(EXIT_FAILURE);
}
在上述示例中,connect()
函数用于将客户端套接字 sockfd
连接到指定的服务器地址 server_addr
。如果连接成功,connect()
函数返回 0,如果连接失败,它会返回 -1,并可以通过 perror()
函数输出错误信息。
connect()
在客户端通常用于发起连接,如果连接成功建立,客户端可以随后使用 send()
和 recv()
函数发送和接收数据。连接失败可能由多种原因引起,例如服务器不可达、连接超时等,因此在实际使用时,通常需要适当处理连接失败的情况。
linux <sys/socket.h> send()详解
在 Linux 的 <sys/socket.h>
头文件中,send()
函数用于通过套接字发送数据到连接的另一端(对于面向连接的套接字,如 TCP 套接字)。这个函数通常用于客户端和服务器之间进行数据通信。
函数原型如下:
1
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
参数解释:
sockfd
:套接字文件描述符,通过socket()
函数创建的套接字描述符。buf
:指向包含要发送数据的缓冲区的指针。len
:要发送的数据的长度。flags
:用于指定发送操作的附加选项,通常设置为 0。
返回值是发送的字节数。如果出现错误,返回 -1,并可以通过 errno
全局变量获取错误码。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 假设 buffer 已经包含了要发送的数据
char buffer[1024] = "Hello, server!";
int send_status = send(sockfd, buffer, strlen(buffer), 0);
if (send_status < 0) {
perror("send failed");
exit(EXIT_FAILURE);
}
在上述示例中,send()
函数用于将存储在 buffer
中的数据通过套接字 sockfd
发送给连接的另一端。如果发送成功,send()
函数返回发送的字节数,如果发送失败,它会返回 -1,并可以通过 perror()
函数输出错误信息。
send()
函数通常与 recv()
函数一起使用,在客户端和服务器之间进行双向数据传输。
linux <sys/socket.h> recv()详解
在 Linux 的 <sys/socket.h>
头文件中,recv()
函数用于从套接字接收数据,即从连接的另一端(对于面向连接的套接字,如 TCP 套接字)接收数据。这个函数通常用于客户端和服务器之间进行数据通信。
函数原型如下:
1
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
参数解释:
sockfd
:套接字文件描述符,通过socket()
函数创建的套接字描述符。buf
:指向存储接收数据的缓冲区的指针。len
:缓冲区的长度,即要接收的数据的最大字节数。flags
:用于指定接收操作的附加选项,通常设置为 0。
返回值是接收的字节数。如果出现错误,返回 -1,并可以通过 errno
全局变量获取错误码。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
char buffer[1024];
int recv_status = recv(sockfd, buffer, sizeof(buffer), 0);
if (recv_status < 0) {
perror("receive failed");
exit(EXIT_FAILURE);
} else if (recv_status == 0) {
printf("Connection closed by peer\n");
} else {
printf("Received data: %s\n", buffer);
}
在上述示例中,recv()
函数用于从套接字 sockfd
接收数据,并将接收到的数据存储在 buffer
缓冲区中。如果接收成功,recv()
函数返回接收到的字节数,如果接收失败,它会返回 -1,并可以通过 perror()
函数输出错误信息。
需要注意的是,recv()
函数在接收数据时会阻塞程序的执行,直到有数据可用或者发生错误。因此,通常在实际应用中,需要结合其他逻辑或者循环来处理接收数据的情况。
linux <sys/socket.h> close()详解
在 Linux 的 <sys/socket.h>
头文件中,close()
函数用于关闭一个文件描述符,包括套接字描述符。在网络编程中,当不再需要使用一个套接字时,应该通过 close()
函数来关闭它,释放资源并结束与该套接字相关联的连接。
函数原型如下:
1
int close(int sockfd);
参数 sockfd
是要关闭的套接字文件描述符。
示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// 其他操作,比如连接、数据传输等...
int close_status = close(sockfd);
if (close_status < 0) {
perror("close failed");
exit(EXIT_FAILURE);
}
在上述示例中,close()
函数被用于关闭之前通过 socket()
函数创建的套接字描述符 sockfd
。如果关闭成功,close()
函数返回 0,如果关闭失败,它会返回 -1,并可以通过 perror()
函数输出错误信息。
在网络编程中,及时关闭不再使用的套接字是很重要的,这可以防止资源泄漏和不必要的资源占用。
sys/socket.h
- 套接字常量、类型和函数的声明。
socket()
- 简述:创建一个
type
类型,domain
协议簇,protocol
通信协议的socket,并返回一个文件描述符 - 声明:
int socket(int domain, int type, int protocol);
- 参数:
domain
– 选择所用的协议族AF_INET
,代表IPv4AF_INET6
,代表IPv6
type
–SOCK_STREAM
, 表示有序,可靠,双工,面向连接的字节流,通常由TCP实现SOCK_DGRAM
, 通过定长的,不可靠消息提供无连接通信,通常由UDP实现
protocol
– 指定特定的通信type使用的协议。- 在大多数实现中,每个type参数只能使用一种协议。
SOCK_STREAM
,使用IPPROTO_TCP
SOCK_DGRAM
, 使用IPPROTO_UDP
- 如果参数为0,则默认设置为1
- 返回值:
- 成功 – 返回文件描述符
- 失败 –
socketpair()
- 简述:创建两个
type
类型,domain
协议簇,protocol
通信协议的,互相连接的socket,将文件描述符放在fds[0]
和fds[1]
- 声明:
int socketpair(int domain, int type, int protocol, int fds[2]);
- 参数:
domain
– 选择所用的协议族AF_INET
,代表IPv4AF_INET6
,代表IPv6
type
–SOCK_STREAM
, 表示有序,可靠,双工,面向连接的字节流,通常由TCP实现SOCK_DGRAM
, 通过定长的,不可靠消息提供无连接通信,通常由UDP实现
protocol
– 指定特定的通信type使用的协议。- 在大多数实现中,每个type参数只能使用一种协议。
SOCK_STREAM
,使用IPPROTO_TCP
SOCK_DGRAM
, 使用IPPROTO_UDP
- 如果参数为0,则默认设置为1
fds[2]
– 存放两个文件描述符的数组 – Input/Output
- 返回值:
- 成功 – 返回0
- 失败 – 返回-1
bind()
- 简述:将套接字通信端点的句柄(
socket FD
)与一个特定的逻辑网络连接关联起来 - 声明:
int bind(int fd, const struct sockaddr *address, socklen_t address_len);
- 参数:
fd
– 通信端点的文件描述符address
– 关联的地址len
– 地址字节长度(the local address which is LEN bytes long)
- 返回值:
- 成功 – 返回0
- 失败 – 返回-1,并设置errno
getsockname()
- 简述:通过本地文件描述符的地址和长度(单位:byte),获取socket名字
- 声明:
int getsockname(int fd, const struct sockaddr *address, socklent *len);
- 参数:
fd
– 文件描述符address
– 地址len
– 长度
- 返回值:
- 成功 –
- 失败 –
connect()
- 简述:创建一个socket文件描述符和地址的连接
- 声明:
int connect(int fd, const struct sockaddr *addr, socklent_t len);
- 参数:
fd
– 文件描述符addr
– 要连接的地址len
– 地址的长度(单位:字节)
- 返回值:
- 成功 – 返回0
- 失败 – 返回-1
send()
- 简述:发送N字节的BUF到socket FD。返回发送的数字或-1。
- 声明:
ssize_t send (int fd, const void *buf, size_t n, int flags);
- 参数:
- 返回值:
recv()
- 简述:从socket FD中读取N个字节,并输入到BUF中
- 声明:
ssize_t recv(int fd, void *buf, size_t n, int flags);
- 参数:
fd
– 文件描述符buf
– 要存放的缓冲区n
– 读取的数据大小flags
–
- 返回值:
- 成功 – 返回读取的字节数
- 失败 – 返回-1
sendto()
- 简述:在socket FD上向地址ADDR(长度为ADDR_LEN)发送N个字节的BUF
- 声明:
ssize_t sendto(int fd, const void *buf, size_t n, int flags, const struct *addr, socklen_t addr_len);
- 参数:
- 返回值:
- 成功 – 返回发送的字节数
- 失败 – 返回-1
recvfrom()
- 简述:通过socket FD读取N个字节到BUF
- 声明:
ssize_t recvfrom(int fd, void *buf, size_t n, int flags, const struct *addr, socklen_t addr_len);
- 参数:
- 返回值:
- 成功 – 返回读取的字节数
- 失败 – 返回-1
- 注意:
- 如果ADDR不为空,将其
*ADDR_LEN
字节填充为发送方的地址,并将地址的实际大小存储在*ADDR_LEN
中。返回读取的字节数或-1错误
- 如果ADDR不为空,将其
sendmsg()
- 简述:在socket FD上发送一个由MESSAGE描述的信息
- 声明:
ssize_t sendmsg(int fd, const struct msghdr *message, int flags);
- 参数:
- 返回值:
- 成功 – 返回发送的字节数
- 失败 – 返回-1
recvmsg()
- 简述:从socket FD接收一个由MESSAGE描述的信息
- 声明:
ssize_t recvmsg(int fd, struct msghdr *message, int flags);
- 参数:
- 返回值:
- 成功 – 返回接收到的字节数
- 失败 – 返回-1
getsockopt()
- 简述:将套接字
FD
的选项OPTNAME
在协议级别level
上的当前值放入OPTVAL
(*OPTLEN
字节长),并将*OPTLEN
设置为该值的实际长度 - 声明:
int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen);
- 返回值:
- 成功 – 返回接收到的字节数
- 失败 – 返回-1
setsockopt()
- 简述:设置套接字
FD
的选项OPTNAME
在协议级别level
为*OPTVAL
(OPTLEN
字节长) - 声明:
int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen);
- 返回值:
- 成功 – 返回接收到的字节数
- 失败 – 返回-1
listen()
- 简述:准备接受套接字FD上的连接。在进一步的请求被拒绝之前,将有N个连接请求排队
- 声明:
int listen(int fd, int n);
- 返回值:
- 成功 – 返回接收到的字节数
- 失败 – 返回-1
accept()
- 简述:在套接字FD上等待连接.
- 当连接到达时,打开一个新的套接字与之通信,将
*ADDR (*ADDR_LEN字节长)
设置为连接对等体的地址,将*ADDR_LEN
设置为地址的实际长度, - 并返回新套接字的描述符,错误则返回-1
- 当连接到达时,打开一个新的套接字与之通信,将
- 声明:
int accept(int fd, const struct sockaddr *addr, socklen_t *addr_len);
- 返回值:
- 成功 – 新套接字的描述符
- 失败 – 返回-1
shutdown()
- 简述:关闭套接字FD上打开的全部或部分连接
- 声明:
int shutdown(int fd, int how);
- 参数:
fd
– 套接字文件描述符how
–SHUT_RD
– 不再接收连接SHUT_WR
– 不再传输数据SHUT_RDWR
– 不再传输数据和接收连接
- 返回值:
- 成功 – 返回0
- 失败 – 返回-1