IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 简单谈谈TCP网络编程API -> 正文阅读

[系统运维]简单谈谈TCP网络编程API

客户机-服务器模型

一个简单的客户机-服务器模型如下图所示。
在这里插入图片描述
客户机需要某个数据或某项服务时,向服务器发送请求,服务器对该请求作出响应,向客户机提供它想要的东西。
一个服务器可以同时对多个客户机作出响应。
客户机和服务器都是以进程(不是机器)为单位的,即客户机进程、服务器进程。

基于TCP的网络编程模型

基于TCP协议的客户机-服务器网络模型执行流程如下:
在这里插入图片描述
服务器进程先启动:

  1. 创建socket
  2. 在socket上绑定指定的IP地址和端口号
  3. 主动socket变被动socket
  4. 监听客户机的连接请求,阻塞等待客户机发起并完成连接

客户机进程后启动:

  1. 创建socket
  2. 向服务器进程发起连接

经过三次握手,TCP连接建立成功后,进程间就可以收发(读写)数据了。此时服务器进程会新增一个执行流,处理客户的请求,原执行流继续阻塞等待新的客户连接,即并发服务器
请求完毕后,客户机进程首先发起断开连接

socket == 套接字
主动socket == 普通的套接字
被动socket == 监听套接字(只存在于服务器进程)
应用程序把socket看作一个文件,使用文件描述符读写它。

套接字地址

套接字地址主要有三个重要信息:地址族(表示哪种套接字)、IP地址端口号
不同类型的套接字定义了不同的结构。

IPV4套接字

/* IPV4套接字地址,32bit值.  */
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };
  
/* 描述IPV4的套接字地址格式  */
struct sockaddr_in
  {
    sa_family_t sin_family; /* 16-bit */
    in_port_t sin_port;     /* 端口号  16-bit*/
    struct in_addr sin_addr;    /* Internet address. 32-bit */
    /* 这里仅仅用作占位符,不做实际用处  */
    unsigned char sin_zero[8];
  };

IPV6套接字

struct sockaddr_in6
  {
    sa_family_t sin6_family; /* 16-bit */
    in_port_t sin6_port;  /* 传输端口号 # 16-bit */
    uint32_t sin6_flowinfo; /* IPv6流控信息 32-bit*/
    struct in6_addr sin6_addr;  /* IPv6地址128-bit */
    uint32_t sin6_scope_id; /* IPv6域ID 32-bit */
  };

本地套接字

struct sockaddr_un {
    unsigned short sun_family; /* 固定为 AF_LOCAL */
    char sun_path[108];   /* 路径名 */
};

通用套接字

/* POSIX.1g 规范规定了地址族为2字节的值.  */
typedef unsigned short int sa_family_t;
/* 描述通用套接字地址  */
struct sockaddr{
    sa_family_t sa_family;  /* 地址族.  16-bit*/
    char sa_data[14];   /* 具体的地址值 112-bit */
  }; 

C语言不支持函数重载,而早期的C语言也没有void *,所以系统定义了一个通用的套接字地址,避免了定义多个功能相同的网络编程API。
API中,凡是用到套接字地址的地方,传入的都是通用套接字类型的指针和它的长度

网络编程API

socket

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

功能:创建socket(主动套接字
参数

  1. domain:地址族。取值有PF_INETIPv4)、PF_INET6IPv6) 、 PF_LOCAL等。

  2. type:通信的数据格式。取值有SOCK_STREAM(字节流,对应TCP)、SOCK_DGRAM(数据报,对应UDP)和SOCK_RAW原始套接字,暂不讨论)。

  3. protocol:暂不讨论,填0即可

返回值:一个整型,表示能对socket进行读写的文件描述符

bind

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

功能:把socket和套接字地址绑定起来。其他进程通过该地址访问该socket。
参数

  1. socket:socket的文件描述符
  2. address:socket通用地址类型的指针
  3. address_len:socket通用地址类型的长度

返回值:成功返回0;失败返回-1

listen

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

功能:把主动套接字变成被动套接字(监听套接字)。用于服务器端。
参数

  1. socket:socket的文件描述符
  2. backlog:这个参数的大小决定了服务器可以接收的并发数目。

返回值:成功返回0,失败返回-1

accept

// #include <sys/socket.h>
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);

功能:服务器等待和客户机完成建立连接
参数

  1. socket:socket的文件描述符
  2. address:用于获取客户机的套接字地址
  3. address_len:用于获取套接字地址的长度

返回值:成功,返回一个非负整型,表示连接套接字的文件描述符;失败返回-1

连接套接字是主动套接字,服务器使用该套接字响应客户机,而监听套接字始终用于监听新的客户连接请求

connect

// #include <sys/types.h>
// #include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, socklen_t address_len);

功能:客户机向服务器发起并完成连接
参数

  1. socket:socket的文件描述符
  2. address服务器的通用套接字地址
  3. address_len:套接字地址长度

返回值:成功返回0;失败返回-1

read

// #include <sys/types.h>
// #include <sys/uio.h>
// #include <unistd.h>
ssize_t read(int fildes, void *buf, size_t nbyte);

功能:从文件fildes里读nbyte字节的数据到首地址buf的缓冲区上。
参数

  1. fildes:文件描述符
  2. buf:缓冲区首地址
  3. nbyte:读取的字节个数

返回值

  1. 正常情况下,返回读到的字节数
  2. 读到EOF,返回0
  3. 其他情况,返回-1

如果read读到了EOF(end-of-file),这在网络中表示对端发送了FIN包,即对端调用了close

write

// #include <unistd.h>
ssize_t write(int fildes, const void *buf, size_t nbyte);

功能:从地址buf开始,把nbyte个字节的数据写到文件fildes
参数

  1. fildes:文件描述符
  2. buf:缓冲区首地址
  3. nbyte:要写入的字节个数

返回值:成功,返回写入的字节数;失败返回-1

close

// #include <unistd.h>
int close(int fildes);

功能:向对端发送FIN包(关闭文件)
参数

  1. fildes:文件描述符

返回值:成功,返回0;失败,返回-1

read、write和close可用于对所有文件的操作。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-09-29 10:44:28  更:2021-09-29 10:46:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 17:36:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码