自学内容网 自学内容网

网络IPC:套接字汇总整理

网络进程间通信(Inter-Process Communication, IPC)中的套接字(Sockets)是一种广泛使用的机制,用于实现不同进程之间通过网络进行数据交换。套接字不仅限于本地进程间通信,也可以用于跨机器通信,使得它成为网络编程的核心技术之一。下面是关于套接字的基本概念、API 和相关操作的汇总整理。

a30f34d9bb2e405eb30c793b624e414d.jpeg

套接字概述

套接字是用于网络通信的端点,可以看作是网络上的一个虚拟连接点。通过套接字,两个进程可以在不同的主机之间建立连接,并通过这个连接进行数据的双向传输。

套接字类型

  • 流套接字(SOCK_STREAM):基于TCP协议,提供面向连接的服务,保证数据按序、无损地传输。
  • 数据报套接字(SOCK_DGRAM):基于UDP协议,提供无连接的服务,数据传输不保证顺序,也不保证无损。

地址家族

  • AF_INET:IPv4地址族,用于IPv4地址。
  • AF_INET6:IPv6地址族,用于IPv6地址。
  • AF_UNIX:Unix域套接字,用于本地进程间通信。

套接字API

创建套接字

  • socket()
    • int socket(int domain, int type, int protocol): 创建一个新的套接字。
    • 参数domain指定地址家族,type指定套接字类型,protocol通常设置为0,表示使用默认协议。

绑定套接字

  • bind()
    • int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 将套接字绑定到特定的地址和端口。
    • 参数sockfd是套接字描述符,addr是指向地址结构的指针,addrlen是地址结构的长度。

监听连接

  • listen()
    • int listen(int sockfd, int backlog): 将套接字置于监听状态。
    • 参数sockfd是套接字描述符,backlog是连接队列的最大长度。

接受连接

  • accept()
    • int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen): 接受客户端的连接请求。
    • 参数sockfd是监听套接字描述符,addraddrlen用于返回客户端的地址信息。

连接到服务器

  • connect()
    • int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen): 连接到服务器。
    • 参数sockfd是套接字描述符,addraddrlen指定服务器的地址信息。

读写数据

  • send()recv()

    • ssize_t send(int sockfd, const void *buf, size_t len, int flags): 向套接字发送数据。
    • ssize_t recv(int sockfd, void *buf, size_t len, int flags): 从套接字接收数据。
    • 参数sockfd是套接字描述符,buf是指向数据缓冲区的指针,len是数据长度,flags可以指定一些选项,如MSG_DONTWAIT表示非阻塞模式。
  • sendto()recvfrom()

    • ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen): 向指定地址发送数据。
    • ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen): 从指定地址接收数据。
    • 这些函数用于无连接的套接字,如UDP。
  • write()read()

    • ssize_t write(int fd, const void *buf, size_t count): 向套接字写入数据。
    • ssize_t read(int fd, void *buf, size_t count): 从套接字读取数据。
    • 这些函数可以用于流套接字,如TCP。

关闭套接字

  • shutdown()

    • int shutdown(int sockfd, int how): 关闭套接字的读、写或读写通道。
    • 参数sockfd是套接字描述符,how指定关闭的方式,如SHUT_RD表示只关闭读通道。
  • close()

    • int close(int sockfd): 关闭套接字。
    • 参数sockfd是套接字描述符。

示例代码

以下是一个简单的 TCP 服务器端示例,展示如何使用 C 语言创建服务器套接字、监听连接、接受客户端连接、读取数据、发送响应、然后关闭连接:

1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <arpa/inet.h>
6#include <sys/socket.h>
7
8#define PORT 8080
9#define MAX_CLIENTS 5
10#define BUFFER_SIZE 1024
11
12int main() {
13    int server_fd, new_socket, valread;
14    struct sockaddr_in address;
15    int opt = 1;
16    int addrlen = sizeof(address);
17    char buffer[BUFFER_SIZE] = {0};
18    char *hello = "Hello from server";
19
20    // 创建套接字
21    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
22        perror("socket failed");
23        exit(EXIT_FAILURE);
24    }
25
26    // 设置选项以允许端口重用
27    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
28        perror("setsockopt");
29        exit(EXIT_FAILURE);
30    }
31
32    address.sin_family = AF_INET;
33    address.sin_addr.s_addr = INADDR_ANY;
34    address.sin_port = htons(PORT);
35
36    // 绑定套接字
37    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
38        perror("bind failed");
39        exit(EXIT_FAILURE);
40    }
41
42    // 监听连接
43    if (listen(server_fd, MAX_CLIENTS) < 0) {
44        perror("listen");
45        exit(EXIT_FAILURE);
46    }
47
48    while (1) {
49        // 接受连接
50        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
51            perror("accept");
52            exit(EXIT_FAILURE);
53        }
54
55        // 读取客户端数据
56        valread = read(new_socket, buffer, BUFFER_SIZE);
57        printf("%s\n", buffer);
58
59        // 发送响应
60        send(new_socket, hello, strlen(hello), 0);
61        printf("Hello message sent\n");
62
63        // 关闭连接
64        close(new_socket);
65    }
66
67    return 0;
68}

注意事项

  • 在进行套接字操作时,务必检查函数的返回值以确保操作成功。
  • 使用套接字后记得及时关闭,以释放系统资源。
  • 处理大文件或大量数据时,考虑使用缓冲或分块读取以提高效率。
  • 跨平台编程时要注意不同操作系统之间的 API 差异。
  • 在处理网络套接字时,要考虑网络延迟和丢包的情况,可以使用超时设置和重试策略来应对这些问题。

套接字是网络编程中的基本组成部分,几乎所有的网络应用都会涉及到套接字的使用。理解和熟练掌握套接字的使用对于编写可靠的网络应用程序至关重要。

 


原文地址:https://blog.csdn.net/suifengme/article/details/140753020

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!