栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

简单谈谈TCP网络编程API

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

简单谈谈TCP网络编程API

文章目录
  • 客户机-服务器模型
  • 基于TCP的网络编程模型
  • 套接字地址
    • IPV4套接字
    • IPV6套接字
    • 本地套接字
    • 通用套接字
  • 网络编程API
    • socket
    • bind
    • listen
    • accept
    • connect
    • read
    • write
    • close

客户机-服务器模型

一个简单的客户机-服务器模型如下图所示。

客户机需要某个数据或某项服务时,向服务器发送请求,服务器对该请求作出响应,向客户机提供它想要的东西。
一个服务器可以同时对多个客户机作出响应。
客户机和服务器都是以进程(不是机器)为单位的,即客户机进程、服务器进程。

基于TCP的网络编程模型

基于TCP协议的客户机-服务器网络模型执行流程如下:

服务器进程先启动:

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

客户机进程后启动:

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

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

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

套接字地址

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

IPV4套接字
typedef uint32_t in_addr_t;
struct in_addr
  {
    in_addr_t s_addr;
  };
  

struct sockaddr_in
  {
    sa_family_t sin_family; 
    in_port_t sin_port;     
    struct in_addr sin_addr;    
    
    unsigned char sin_zero[8];
  };
IPV6套接字
struct sockaddr_in6
  {
    sa_family_t sin6_family; 
    in_port_t sin6_port;  
    uint32_t sin6_flowinfo; 
    struct in6_addr sin6_addr;  
    uint32_t sin6_scope_id; 
  };
本地套接字
struct sockaddr_un {
    unsigned short sun_family; 
    char sun_path[108];   
};
通用套接字
typedef unsigned short int sa_family_t;

struct sockaddr{
    sa_family_t sa_family;  
    char sa_data[14];   
  }; 

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

网络编程API socket
// #include 
int socket(int domain, int type, int protocol);

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

  1. domain:地址族。取值有PF_INET(IPv4)、PF_INET6(IPv6) 、 PF_LOCAL等。

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

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

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

bind
// #include 
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 
int listen(int socket, int backlog);

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

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

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

accept
// #include 
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);

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

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

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

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

connect
// #include 
// #include 
int connect(int socket, const struct sockaddr *address, socklen_t address_len);

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

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

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

read
// #include 
// #include 
// #include 
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 
ssize_t write(int fildes, const void *buf, size_t nbyte);

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

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

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

close
// #include 
int close(int fildes);

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

  1. fildes:文件描述符

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/276957.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号