当前位置: 首页 > news >正文

Socket API 核心函数详解

Socket API 核心函数详解

一、TCP 核心函数
1. socket() - 创建套接字

c

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

  • 功能:创建一个套接字描述符,用于后续网络通信。
  • 参数
    • domain:协议族(如AF_INET表示 IPv4,AF_INET6表示 IPv6)。
    • type:套接字类型(如SOCK_STREAM表示 TCP,SOCK_DGRAM表示 UDP)。
    • protocol:通常为 0,表示自动选择对应类型的默认协议。
  • 返回值:成功返回套接字描述符(非负整数),失败返回-1
  • 示例

    c

    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
    
2. bind() - 绑定地址和端口

c

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

  • 功能:将套接字与指定的 IP 地址和端口号绑定。
  • 参数
    • sockfdsocket()返回的套接字描述符。
    • addr:指向struct sockaddr的指针,包含 IP 地址和端口信息。
    • addrlen:地址结构的长度。
  • 返回值:成功返回 0,失败返回-1
  • 示例

    c

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定所有可用接口
    server_addr.sin_port = htons(8888);       // 端口号需转换为网络字节序
    bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
3. listen() - 监听连接

c

#include <sys/socket.h>
int listen(int sockfd, int backlog);

  • 功能:将套接字设置为被动模式(监听模式),等待客户端连接。
  • 参数
    • sockfd:套接字描述符。
    • backlog:允许的最大连接请求队列长度(如SOMAXCONN表示系统默认值)。
  • 返回值:成功返回 0,失败返回-1
  • 示例

    c

    listen(sockfd, SOMAXCONN); // 监听客户端连接
    
4. accept() - 接受连接

c

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

  • 功能:从等待连接队列中取出一个连接请求,创建新的套接字用于与客户端通信。
  • 参数
    • sockfd:监听套接字描述符。
    • addr:存储客户端地址信息的结构体指针(可设为NULL)。
    • addrlen:地址结构长度的指针。
  • 返回值:成功返回新的客户端套接字描述符,失败返回-1
  • 示例

    c

    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    int connfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_addr_len);
    // connfd 用于与客户端通信
    
5. connect() - 建立连接(客户端)

c

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

  • 功能:客户端向服务器发起连接请求。
  • 参数
    • sockfd:客户端套接字描述符。
    • addr:服务器地址信息结构体指针。
    • addrlen:地址结构长度。
  • 返回值:成功返回 0,失败返回-1
  • 示例

    c

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器IP
    server_addr.sin_port = htons(8888);                   // 服务器端口
    connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
6. send()/recv() - 发送 / 接收数据

c

#include <sys/socket.h>
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,或设置特殊标志(如MSG_DONTWAIT表示非阻塞)。
  • 返回值
    • send():成功返回实际发送的字节数,失败返回-1
    • recv():返回接收到的字节数,连接关闭返回 0,失败返回-1
  • 示例

    c

    // 发送数据
    char *msg = "Hello, server!";
    send(sockfd, msg, strlen(msg), 0);// 接收数据
    char buffer[1024];
    int n = recv(sockfd, buffer, sizeof(buffer), 0);
    if (n > 0) buffer[n] = '\0'; // 确保字符串以'\0'结尾
    
二、UDP 核心函数
1. sendto() - 发送 UDP 数据报

c

#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);

  • 功能:向指定目标地址发送 UDP 数据报(无需预先连接)。
  • 参数
    • 前 4 个参数与send()相同。
    • dest_addr:目标地址结构体指针。
    • addrlen:地址结构长度。
  • 返回值:成功返回发送的字节数,失败返回-1
  • 示例

    c

    struct sockaddr_in server_addr;
    // 设置服务器地址...
    char *msg = "Hello, UDP server!";
    sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
2. recvfrom() - 接收 UDP 数据报

c

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);

  • 功能:接收 UDP 数据报,并获取发送方的地址信息。
  • 参数
    • 前 4 个参数与recv()相同。
    • src_addr:存储发送方地址的结构体指针(可设为NULL)。
    • addrlen:地址结构长度的指针。
  • 返回值:成功返回接收的字节数,失败返回-1
  • 示例

    c

    struct sockaddr_in client_addr;
    socklen_t client_addr_len = sizeof(client_addr);
    char buffer[1024];
    int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_addr_len);
    
三、TCP 与 UDP 的核心区别
特性TCPUDP
连接方式面向连接(需三次握手)无连接
可靠性可靠(自动重传、排序)不可靠(可能丢包、乱序)
传输效率较低(有确认机制)较高(无额外开销)
数据形式字节流(无边界)数据报(有边界)
适用场景文件传输、HTTP、SMTP 等实时音视频、DNS、游戏等
核心函数connect()accept()send()recv()sendto()recvfrom()
四、常见错误处理
  1. bind()失败(EADDRINUSE

    • 原因:端口已被占用。
    • 解决:使用setsockopt()设置SO_REUSEADDR选项重用端口。

    c

    int opt = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
  2. accept()返回EAGAINEWOULDBLOCK

    • 原因:在非阻塞模式下没有连接请求。
    • 解决:继续处理其他事件或等待下一次epoll_wait()
  3. recv()返回 0

    • 原因:对方关闭了连接。
    • 解决:关闭对应的套接字。
  4. send()/recv()返回-1errnoEINTR

    • 原因:系统调用被信号中断。
    • 解决:重试操作。
五、总结
  • TCP 函数流程
    服务器:socket() → bind() → listen() → accept() → send()/recv()
    客户端:socket() → connect() → send()/recv()

  • UDP 函数流程
    发送方:socket() → sendto()
    接收方:socket() → bind() → recvfrom()

掌握这些核心函数是实现网络编程的基础,不同函数的组合和参数设置决定了网络程序的行为(如阻塞 / 非阻塞、面向连接 / 无连接)。

分享

相关文章:

  • 万字解析:Java字符串
  • Three.js知识框架
  • rhel8.1 无法安装应用(提示需要注册系统)
  • 多线程与线程互斥
  • sip协议栈--sip结构分析
  • 一文理解扩散模型(生成式AI模型)(2)
  • 编程的本质, 就是创造工具
  • 架构设计不合理,如何优化系统结构
  • 【Linux】多路转接epoll、Linux高并发I/O多路复用
  • 【Linux】基础指令(Ⅱ)
  • 第十九次博客打卡
  • 可变形卷积简介(Deformable Convolution)
  • vLLM - SamplingParams 参数
  • Linux服务之lvs集群与dr模式部署
  • Mathematics-2025《Semi-Supervised Clustering via Constraints Self-Learning》
  • 线程同步机制
  • FlashInfer - 测试的GPU H100 SXM、A100 PCIe、RTX 6000 Ada、RTX 4090
  • Docker 介绍与使用
  • Mysql 存储引擎
  • 系统漏洞扫描服务:维护网络安全的关键与服务原理?
  • 美F-35险被胡塞武装击中,损失增大让行动成“烂尾仗”
  • 百色一女子称家委会强制排班被迫抱婴儿校门口站岗?区教育局:自愿参与
  • 奥古斯都时代的历史学家李维
  • 山西临汾哪吒主题景区回应雕塑被指抄袭:造型由第三方公司设计
  • 中拉论坛部长级会议为何悬挂海地和圣卢西亚的国旗?外交部回应
  • 广东:十年后省级水网主骨架全面建成,与国家骨干网互联互通