Socket套接字与TCP实现框架

文章目录

Socket套接字

latex 复制代码
┌─────────────────┐
│   应用程序      │
├─────────────────┤
│  Socket API     │ ← 网络编程接口
├─────────────────┤
│   传输层(TCP/UDP) │
├─────────────────┤
│   网络层(IP)     │
├─────────────────┤
│   链路层/物理层  │
└─────────────────┘
  • 套接字属于一种特殊的文件描述符
  • UNIX域套接字用于进程间通信

Scoket概念

  • 定义:应用层与TCP/IP协议族通信的中间软件抽象层,是一组API
  • 作用:网络通信的端点,包含IP地址 + 端口号 + 协议三元组
    • IP地址:标识计算机
    • 端口号:标识计算机当中的进程
    • 协议:指定数据传输的方式
  • 本质:特殊的文件描述符,可以通过文件I/O函数(read/write)操作

常见的网络编程接口

  • Berkeley Socket:UNIX/Linux标准,POSIX规范
  • Windows Socket (Winsock):Windows平台的socket实现
  • TLI (Transport Layer Interface):AT&T UNIX的传输层接口

Socket地址结构

通用地址结构(用于类型转换)

c 复制代码
#include <sys/socket.h>

// 通用地址结构体(所有专用结构体都要转换为这个类型)
struct sockaddr {
    sa_family_t sa_family;    // 地址族:AF_XXX
    char        sa_data[14];  // 地址数据
};
  • AF_UNIX:使用本地域套接字的地址结构,用于本地通信
  • AF_INET: 使用IPv4的通信地址结构
  • AF_INET6:使用IPv6的通信地址结构

IPv4专用地址结构(最常用)

c 复制代码
#include <netinet/in.h>

// IPv4地址结构体
struct sockaddr_in {
    sa_family_t    sin_family;   // 地址族:AF_INET
    in_port_t      sin_port;     // 端口号(网络字节序)
    struct in_addr sin_addr;     // IPv4地址
};

// IPv4地址(32位)
struct in_addr {
    uint32_t       s_addr;       // IPv4地址(网络字节序)
};

IPv6专用地址结构

c 复制代码
#include <netinet/in.h>

// IPv6地址结构体
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;     // IPv6地址
    uint32_t        sin6_scope_id; // 作用域ID
};

// IPv6地址(128位)
struct in6_addr {
    unsigned char   s6_addr[16];   // IPv6地址
};

套接字类型

三种主要类型

类型 常量 协议 特点 适用场景
流式套接字 SOCK_STREAM TCP 可靠、面向连接、字节流 文件传输、HTTP、SSH
数据报套接字 SOCK_DGRAM UDP 不可靠、无连接、数据报 DNS、音视频流、实时游戏
原始套接字 SOCK_RAW 直接IP层 直接操作底层协议 网络工具开发(ping/traceroute)

选择原则

c 复制代码
// TCP套接字(嵌入式服务器常用)
int tcp_sock = socket(AF_INET, SOCK_STREAM, 0);

// UDP套接字(嵌入式传感器数据上报)
int udp_sock = socket(AF_INET, SOCK_DGRAM, 0);

// 原始套接字(网络诊断工具)
int raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

TCP通信实现框架

  • 通信之前,客户端和服务器端先创建套接字
  • 服务器端调用 bind,把端口号和本地 IP 地址填写到已创建的套接字中
  • 服务器端调用 listen(收听),把套接字设置为被动方式,以便随时接受客户的服务请求。UDP 服务器不使用 listen 系统调用
  • 服务器端调用 accept(接受),以便把远地客户进程发来的连接请求提取出来。UDP 服务器不使用 accept 系统调用
  • 客户端进程调用 connect,以便和远地服务器建立连接
  • 客户端和服务器在 TCP 连接上使用 write传送数据,使用 read接收数据
  • 客户端或服务器通信结束,调用 close 释放连接和撤销套接字

三次握手在框架中的体现

latex 复制代码
客户端               服务器端
  │                    │
  │      SYN=1         │
  ├───────────────────>│ socket() + bind() + listen()
  │                    │
  │   SYN=1, ACK=1     │
  │<───────────────────┤ accept()阻塞等待连接
  │                    │
  │      ACK=1         │
  ├───────────────────>│ accept()返回,连接建立
  │                    │
  │     数据交换        │
  │<──────────────────>│
相关推荐
Jony_19 小时前
高可用移动网络连接
网络协议
chilix1 天前
Linux 跨网段路由转发配置
网络协议
DianSan_ERP3 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
呉師傅3 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑
gihigo19983 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
2501_946205523 天前
晶圆机器人双臂怎么选型?适配2-12寸晶圆的末端效应器有哪些?
服务器·网络·机器人
linux kernel3 天前
第七部分:高级IO
服务器·网络
数字护盾(和中)3 天前
BAS+ATT&CK:企业主动防御的黄金组合
服务器·网络·数据库
~远在太平洋~3 天前
Debian系统如何删除多余的kernel
linux·网络·debian
龙仔7253 天前
在麒麟V10服务器安全加固,sshd防暴力破解加固,实现“密码错误3次封IP”的需求
服务器·tcp/ip·安全