温馨提示×

Linux进程网络编程:socket接口详解

小樊
70
2025-05-19 10:23:12
栏目: 智能运维

在Linux系统中,套接字(socket)是一种用于实现进程间通信(IPC)的机制,它允许不同进程通过网络进行数据交换。套接字接口是Linux网络编程的基础,提供了丰富的函数和选项来支持各种网络协议和功能。

以下是Linux套接字接口的一些关键概念和组件:

1. 套接字类型

  • 流式套接字(SOCK_STREAM):基于TCP协议,提供可靠的、面向连接的通信。
  • 数据报套接字(SOCK_DGRAM):基于UDP协议,提供无连接的、不可靠的通信。
  • 原始套接字(SOCK_RAW):允许直接访问底层网络协议,通常用于网络协议开发和调试。

2. 套接字地址结构

  • IPv4地址结构(sockaddr_in)
    struct sockaddr_in {
        sa_family_t    sin_family; // 地址族,通常是AF_INET
        in_port_t      sin_port;   // 端口号
        struct in_addr sin_addr;   // IP地址
        char           sin_zero[8]; // 保留字段,必须为0
    };
    
  • IPv6地址结构(sockaddr_in6)
    struct sockaddr_in6 {
        sa_family_t    sin6_family; // 地址族,通常是AF_INET6
        in_port_t      sin6_port;   // 端口号
        uint32_t       sin6_flowinfo; // 流信息(IPv6扩展头)
        struct in6_addr sin6_addr;   // IP地址
        uint32_t       sin6_scope_id; // 作用域ID(例如接口索引)
    };
    

3. 套接字创建与绑定

  • 创建套接字
    int socket(int domain, int type, int protocol);
    
  • 绑定套接字到地址
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    

4. 监听与接受连接

  • 监听连接请求
    int listen(int sockfd, int backlog);
    
  • 接受连接请求
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    

5. 连接与发送/接收数据

  • 连接到远程地址
    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
  • 发送数据
    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);
    

6. 关闭套接字

  • 关闭套接字
    int close(int sockfd);
    

7. 其他有用的函数和宏

  • 获取本地地址
    int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
  • 获取远程地址
    int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
  • 设置套接字选项
    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
    
  • 获取套接字选项
    int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
    

示例代码

以下是一个简单的TCP服务器示例,使用流式套接字:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>

#define PORT 8080

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";

    // 创建套接字文件描述符
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置套接字选项
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字到地址
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听连接
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 接受连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    // 读取数据
    read(new_socket, buffer, 1024);
    printf("Message from client: %s\n", buffer);

    // 发送数据
    send(new_socket, hello, strlen(hello), 0);
    printf("Hello message sent\n");

    // 关闭套接字
    close(new_socket);
    close(server_fd);

    return 0;
}

这个示例展示了如何创建一个TCP服务器,绑定到指定端口,监听连接请求,接受连接,并进行简单的读写操作。

通过这些基础知识和示例代码,你可以开始在Linux系统上进行网络编程。根据具体需求,你可能需要进一步学习和使用更高级的套接字选项和功能。

0