处理端口和 IP 地址

以下是 Linux 网络通信核心函数的详细参数说明及示例代码,涵盖 TCP/UDP 的关键接口:


**1. socket() - 创建套接字

函数原型
c 复制代码
int socket(int domain, int type, int protocol);
参数说明
参数 说明
domain 协议族:AF_INET (IPv4)、AF_INET6 (IPv6)、AF_UNIX (本地通信)
type 套接字类型:SOCK_STREAM (TCP)、SOCK_DGRAM (UDP)
protocol 通常填 0,由系统自动选择(如 TCP 或 UDP)
示例
c 复制代码
// 创建 TCP 套接字
int tcp_sock = socket(AF_INET, SOCK_STREAM, 0);
if (tcp_sock == -1) {
    perror("socket");
    exit(EXIT_FAILURE);
}

// 创建 UDP 套接字
int udp_sock = socket(AF_INET, SOCK_DGRAM, 0);

**2. bind() - 绑定地址

函数原型
c 复制代码
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数说明
参数 说明
sockfd 套接字描述符
addr 指向 sockaddr_in 结构体的指针(存储 IP 和端口信息)
addrlen 地址结构体的长度(sizeof(struct sockaddr_in)
示例
c 复制代码
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;                   // IPv4
addr.sin_port = htons(8080);                 // 端口 8080(转换为网络字节序)
addr.sin_addr.s_addr = htonl(INADDR_ANY);    // 绑定到所有本地 IP

if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    perror("bind");
    close(sockfd);
    exit(EXIT_FAILURE);
}

**3. listen() - 监听连接(TCP)

函数原型
c 复制代码
int listen(int sockfd, int backlog);
参数说明
参数 说明
sockfd 已绑定的套接字描述符
backlog 等待连接队列的最大长度(通常设为 5~10)
示例
c 复制代码
if (listen(sockfd, 5) == -1) {
    perror("listen");
    close(sockfd);
    exit(EXIT_FAILURE);
}

**4. accept() - 接受连接(TCP)

函数原型
c 复制代码
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数说明
参数 说明
sockfd 处于监听状态的套接字描述符
addr 用于保存客户端地址信息的结构体指针(可为 NULL
addrlen 地址结构体的长度指针(可为 NULL
示例
c 复制代码
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
if (client_fd == -1) {
    perror("accept");
    close(sockfd);
    exit(EXIT_FAILURE);
}

printf("Client connected from %s:%d\n",
       inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

**5. connect() - 连接服务器(TCP/UDP)

函数原型
c 复制代码
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
示例(TCP)
c 复制代码
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("192.168.1.100");  // 服务器 IP

if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
    perror("connect");
    close(sockfd);
    exit(EXIT_FAILURE);
}

**6. send() / recv() - 发送/接收数据(TCP)

函数原型
c 复制代码
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 控制标志(通常填 0
示例
c 复制代码
// 发送数据
char *msg = "Hello, Server!";
if (send(client_fd, msg, strlen(msg), 0) == -1) {
    perror("send");
}

// 接收数据
char buffer[1024];
ssize_t n = recv(client_fd, buffer, sizeof(buffer), 0);
if (n == -1) {
    perror("recv");
} else if (n == 0) {
    printf("Connection closed\n");
} else {
    buffer[n] = '\0';
    printf("Received: %s\n", buffer);
}

**7. sendto() / recvfrom() - 发送/接收数据(UDP)

函数原型
c 复制代码
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);
示例
c 复制代码
// UDP 发送数据到指定地址
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(8080);
dest_addr.sin_addr.s_addr = inet_addr("192.168.1.100");

sendto(udp_sock, "Hello", 5, 0,
       (struct sockaddr*)&dest_addr, sizeof(dest_addr));

// UDP 接收数据并获取来源地址
struct sockaddr_in src_addr;
socklen_t src_len = sizeof(src_addr);
char buffer[1024];
recvfrom(udp_sock, buffer, sizeof(buffer), 0,
         (struct sockaddr*)&src_addr, &src_len);

**8. close() - 关闭套接字

函数原型
c 复制代码
int close(int sockfd);
示例
c 复制代码
close(client_fd);  // 关闭客户端套接字
close(server_fd);  // 关闭服务端套接字

**9. setsockopt() - 设置套接字选项

函数原型
c 复制代码
int setsockopt(int sockfd, int level, int optname,
               const void *optval, socklen_t optlen);
示例(设置地址重用)
c 复制代码
int reuse = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
    perror("setsockopt");
}

完整 TCP 服务端示例

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

int main() {
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 设置地址重用
    int reuse = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("bind");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, 5) == -1) {
        perror("listen");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port 8080...\n");

    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);
        if (client_fd == -1) {
            perror("accept");
            continue;
        }

        char *response = "HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!";
        send(client_fd, response, strlen(response), 0);
        close(client_fd);
    }

    close(server_fd);
    return 0;
}

总结

  • 函数协作流程
    • TCP 服务端socket()bind()listen()accept()send()/recv()close()
    • TCP 客户端socket()connect()send()/recv()close()
    • UDP 通信socket()bind()(可选) → sendto()/recvfrom()close()
  • 关键细节
    • 字节序转换 :使用 htons(), ntohs() 等函数处理端口和 IP 地址。
    • 错误处理:所有函数调用后需检查返回值。
    • 资源释放 :通信结束后必须调用 close() 关闭套接字。
相关推荐
悟能不能悟1 分钟前
cmd什么命令可以知道本机到目标机的ip节点
网络·网络协议·tcp/ip
cliproxydaili4 分钟前
代理IP+账号矩阵:Cliproxy与TGX Account如何赋能品牌全球化表达?
网络协议·tcp/ip·矩阵
六点半88826 分钟前
【计算机网络】初识网络(TCP / IP五层模型 + 网络协议栈和操作系统关系 + 网络传输基本流程 + 数据包封装和分用)
网络·计算机网络
小亮亮虫29 分钟前
LwIP UDP RAW
单片机·网络协议·udp
仰望星空的凡人40 分钟前
【BUG排查】基于RH850F1KMS1的主控出现系统中断错误,调试FEIC的值为0x11
单片机·bug·rh850·renesas
风清再凯1 小时前
03-docker存储与网络
网络·docker·容器
螺丝钉的扭矩一瞬间产生高能蛋白2 小时前
STM32电机控制基础知识
stm32·单片机·嵌入式硬件·嵌入式软件·直流有刷电机控制·定时器互补输出·定时器死区控制刹车输入
沐欣工作室_lvyiyi2 小时前
基于腾讯云的物联网导盲助手设计与实现(论文+源码)
单片机·物联网·云计算·毕业设计·腾讯云·导盲杖
九河云3 小时前
在云计算环境中实施有效的数据安全策略
大数据·网络·数据库·云计算
Blossom.1183 小时前
用一颗MCU跑通7B大模型:RISC-V+SRAM极致量化实战
人工智能·python·单片机·嵌入式硬件·opencv·机器学习·risc-v