Socket 网络编程核心 API 详解

Socket 网络编程是构建网络应用的基础,核心 API 涵盖了套接字创建、地址绑定、连接管理、数据传输等关键操作。以下是主要函数的功能说明、参数解析及示例代码:


1. 套接字创建与配置

socket():创建套接字
  • 功能:创建通信端点,返回套接字描述符。
  • 原型
    int socket(int domain, int type, int protocol);
  • 参数
    • domain:地址族(如 AF_INET(IPv4)、AF_INET6(IPv6))。
    • type:套接字类型(SOCK_STREAM(TCP)、SOCK_DGRAM(UDP))。
    • protocol:协议(通常设为 0,自动选择)。
  • 示例
    int tcp_sock = socket(AF_INET, SOCK_STREAM, 0);  // TCP 套接字
    int udp_sock = socket(AF_INET, SOCK_DGRAM, 0);   // UDP 套接字
bind():绑定地址和端口
  • 功能:将套接字与本地地址和端口绑定(服务端使用)。
  • 原型
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 示例​(IPv4):
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);        // 端口转换为网络字节序
    addr.sin_addr.s_addr = INADDR_ANY;  // 绑定所有接口
    bind(sock, (struct sockaddr*)&addr, sizeof(addr));

2. 连接管理

listen():监听连接(TCP 服务端)​
  • 功能:设置服务端套接字为监听状态,等待客户端连接。
  • 原型
    int listen(int sockfd, int backlog);
  • 参数
    • backlog:等待连接队列的最大长度(如 5)。
  • 示例
    listen(sock, 5);  // 允许最多5个等待连接
connect():建立连接(TCP 客户端)​
  • 功能:客户端主动连接到服务端。
  • 原型
    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 示例
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(80);     // HTTP 端口
    inet_pton(AF_INET, "93.184.216.34", &serv_addr.sin_addr);  // example.com
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
accept():接受连接(TCP 服务端)​
  • 功能:接受客户端连接,返回新的套接字用于通信。
  • 原型
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • 示例
    struct sockaddr_in client_addr;
    socklen_t addr_len = sizeof(client_addr);
    int client_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);

3. 数据传输

send() 和 recv():面向连接(TCP)​
  • send():发送数据。
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
  • recv():接收数据。
    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • 示例
    char msg[] = "Hello, Server!";
    send(client_sock, msg, strlen(msg), 0);  // 发送数据
    
    char buffer[1024];
    ssize_t bytes = recv(client_sock, buffer, sizeof(buffer), 0); // 接收数据
sendto() 和 recvfrom():无连接(UDP)​
  • sendto():发送数据到指定地址。
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                  const struct sockaddr *dest_addr, socklen_t addrlen);
  • recvfrom():接收数据并获取发送方地址。
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                    struct sockaddr *src_addr, socklen_t *addrlen);
  • 示例
    // 发送数据到目标地址
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "192.168.1.2", &dest_addr.sin_addr);
    sendto(udp_sock, msg, strlen(msg), 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
    
    // 接收数据并获取来源地址
    struct sockaddr_in src_addr;
    socklen_t addr_len = sizeof(src_addr);
    recvfrom(udp_sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&src_addr, &addr_len);

4. 关闭连接

close():关闭套接字
  • 功能:释放套接字资源。
  • 原型
    int close(int sockfd);
  • 示例
    close(client_sock);  // 关闭客户端套接字
    close(sock);         // 关闭服务端套接字

5. 错误处理

  • 检查返回值:所有函数返回 -1 表示失败。
  • 错误信息:使用 perror() 或 strerror(errno) 获取错误描述。
    if (connect(sock, ...) == -1) {
        perror("connect failed");
        exit(EXIT_FAILURE);
    }

代码示例:TCP 服务端与客户端

服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main() {
    int server_fd, client_sock;
    struct sockaddr_in addr;
    char buffer[1024] = {0};

    // 1. 创建 TCP 套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0);

    // 2. 绑定地址和端口
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    addr.sin_addr.s_addr = INADDR_ANY;
    bind(server_fd, (struct sockaddr*)&addr, sizeof(addr));

    // 3. 监听连接
    listen(server_fd, 5);

    // 4. 接受连接
    client_sock = accept(server_fd, NULL, NULL);

    // 5. 接收并响应数据
    read(client_sock, buffer, sizeof(buffer));
    printf("Client: %s\n", buffer);
    send(client_sock, "Hello from server!", 18, 0);

    // 6. 关闭连接
    close(client_sock);
    close(server_fd);
    return 0;
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    int sock;
    struct sockaddr_in serv_addr;

    // 1. 创建 TCP 套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);

    // 2. 连接服务端
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8080);
    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    // 3. 发送并接收数据
    send(sock, "Hello from client!", 18, 0);
    char buffer[1024] = {0};
    read(sock, buffer, sizeof(buffer));
    printf("Server: %s\n", buffer);

    // 4. 关闭连接
    close(sock);
    return 0;
}

总结

API用途TCPUDP
socket()创建套接字✔️✔️
bind()绑定地址和端口✔️✔️
listen()监听连接(服务端)✔️
accept()接受连接(服务端)✔️
connect()建立连接(客户端)✔️✔️*
send()/recv()面向连接数据传输✔️
sendto()/recvfrom()无连接数据传输✔️
close()关闭套接字✔️✔️

:UDP 的 connect() 用于固定通信地址,但非必需。

掌握这些核心 API 后,您可构建 TCP/UDP 客户端和服务端程序,处理网络通信中的连接、数据传输和错误场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浩瀚之水_csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值