socket八股

1. socket() 函数简介#

socket() 函数是创建一个套接字(socket)以进行网络通信的系统调用。套接字可以用于 TCP(面向连接)或 UDP(无连接)的通信。调用 socket() 函数时,需要指定协议族、套接字类型和协议。

socket() 函数原型:#

#include <sys/socket.h>

int socket(int domain, int type, int protocol);
  • domain:指定通信协议族(地址族),常见的值有:

    • AF_INET:IPv4 网络协议。
    • AF_INET6:IPv6 网络协议。
    • AF_UNIX:本地通信(Unix域套接字)。
  • type:指定套接字类型,常见的值有:

    • SOCK_STREAM:字节流(面向连接,TCP)。
    • SOCK_DGRAM:数据报(无连接,UDP)。
    • SOCK_RAW:原始套接字,允许访问底层协议。
  • protocol:指定使用的协议,一般为 0,让系统自动选择合适的协议。

    • 对于 SOCK_STREAM,协议是 TCP。
    • 对于 SOCK_DGRAM,协议是 UDP。

示例:#

int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);  // 创建一个 TCP 套接字

2. 阻塞和非阻塞模式#

阻塞模式#

默认情况下,套接字是以阻塞模式运行的。这意味着,当调用例如 recv()send() 等阻塞系统调用时,程序会等待数据的接收或发送操作完成后才返回。例如,当一个套接字在等待数据时,调用 recv() 函数会一直阻塞,直到接收到数据或发生错误。

非阻塞模式#

非阻塞模式下,系统调用会立即返回,而不会等待操作完成。这样,程序可以在不阻塞的情况下执行其他任务,而不是等待某些操作完成。

使用 fcntl() 设置非阻塞模式:#

可以使用 fcntl() 函数将套接字设置为非阻塞模式:

#include <fcntl.h>
#include <unistd.h>

// 将套接字设置为非阻塞模式
void set_nonblocking(int sockfd) {
    int flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
}

当套接字是非阻塞时,像 recv()send() 这样的系统调用会立即返回:

  • 如果没有数据可读,recv() 会返回 -1,并将 errno 设置为 EAGAINEWOULDBLOCK
  • 如果无法发送数据,send() 也会返回 -1,并将 errno 设置为 EAGAIN

3. Socket 通信的流程#

下面是一个标准的 TCP 套接字通信流程,分为 服务器端客户端

服务器端的流程:#

  1. 创建套接字:使用 socket() 函数创建一个套接字。
  2. 绑定套接字:使用 bind() 函数将套接字绑定到一个本地地址和端口。
  3. 监听连接:使用 listen() 函数监听客户端连接请求。
  4. 接受连接:使用 accept() 函数接受客户端的连接。
  5. 收发数据:使用 recv()send() 函数接收和发送数据。
  6. 关闭连接:使用 close() 函数关闭套接字。

客户端的流程:#

  1. 创建套接字:使用 socket() 函数创建一个套接字。
  2. 连接服务器:使用 connect() 函数连接到服务器。
  3. 收发数据:使用 recv()send() 函数接收和发送数据。
  4. 关闭连接:使用 close() 函数关闭套接字。
posted @   xiazichengxi  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
主题色彩