• 介绍


    一些概念

    当编写Linux网络程序时,通常做法是编写一个服务端和一个客户端,在程序中要用到以下数据结构及系统调用:

    #include <netinet/in.h> /*for struct sockaddr_in*/
    #include <unistd.h> /*for write,read*/
    #include <sys/types.h>
    #include <sys/socket.h> /*for other system calls*/
    
    struct sockaddr_in;
    int socket(int domain, int type, int protocol);
    
    /*server需要指定端口:区分lintening socket以及connected socket
    只有一个lintening socket,可以有多个connected socket 
    未连接的数据报发向listening socket
    已连接的数据报发向connted socked*/
    int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    int listen(int sockfd, int backlog);
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
    /*client:使用传输协议指定的临时端口。*/
    struct sockaddr_in;
    int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
    
    /*common*/
    ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
    ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
    ssize_t write(int fd, const void *buf, size_t count);
    ssize_t read(int fd, void *buf, size_t count);
    int close(int fd);
    

    经典的OSI模型:

    1~4层主要处理通信细节,通常作为系统内核的一部分。
    5~7层主要处理应用逻辑,通常构成用户进程。

    UDP与TCP

    UDP

    User Datagram Protocol:UDP是不可靠的传输层协议,其长度包含在发送的数据中。协议不保证数据报的顺序,不保证数据报会到达
    目的地,也不保证数据报只会到达一次。我们可以在程序中应用一些机制来进行确认,例如应答机制,超时机制,重发机制等。UDP
    是无连接的,即客户端与服务端之间不需要长连接。

    TCP

    TCP是基于连接的协议,并且提供可靠性,它要求对端进行应答,如果在一定时间内没有收到应答将进行一定次数的重发,如果仍未
    成功,TCP放弃发送数据,断开连接并通知用户。TCP使用了动态估算往返时间(round-trip time)的算法,并且在连接期间持续估算
    ,所以协议知道应当为应答设置多久的等待时间。
    TCP将发送的每字节数据都关联序列号以对数据进行排序,并且还可以根据序列号对数据去重。
    TCP提供流控制,协议通知对端在某一时刻,它能够从对端接收多少字节,称为通知窗口(advertised window),就是当前接收端可用
    的缓存空间,以保证不会溢出缓冲区。窗口是动态变化的,当接受到数据时,窗口空间减少;当数据被读取后,窗口空间增加。当窗
    口空间减少到0时,必须等待数据被读取后才能继续接收。
    TCP连接是全双工的。连接双方可以同时双向发送或接收数据。因此,协议必须为每个方向的数据流记录状态信息。连接建立后也可
    以变成单工的。

    三次握手

    1. 服务端通过socket,bind,listen等调用被动打开连接
    2. 客户端调用connent打开主动连接。客户端发送SYN包,向服务端告知其序列号
    3. 服务端应答(ACK)客户端的SYN,并且发送其SYN
    4. 客户端应答ACK服务端的SYN

    四次挥手

    1. 一端调用close,这一端称为主动关闭,发送FIN包
    2. 另一端收到FIN包,称为被动关闭。TCP会对收到的FIN进行应答。FIN向接收数据加上EOF标志,即此端无法收到数据
    3. 一段时间后,被动关闭端读到EOF,调用close,TCP发送FIN包
    4. 主动关闭方收到FIN,进行应答

    在2,3步之间,数据仍可能由被动关闭方传向主动关闭方,称为半关闭。
    任何一端都可以主动关闭。除了调用close,当程序终止时,所有打开的描述符都被关闭,也会发送FIN包。

    TCP状态转换图


    共有11种状态

    TIME_WAIT状态

    上图中看到,主动关闭的一方要经过这一状态。这一状态持续时间为2倍的最长报文寿命(maximum segment lifetime)。MSL是IP数据报在网络中存活的最长时间。每个数据报都包含8位的跳限制,最大为255。跳限制为255的数据报存活时间也不能超过MSL。数据包在网络中丢失通常是路由异常的原因。假设一个TCP包丢失并且被超时重发,重发的包经由其他路由路径到达目的地。但是在不多于MSL时间之后,路由恢复,之前丢失的包也到达了,TCP必须处理这些重复情况。
    TIME_WAIT状态有两个原因:

    1. 实现TCP可靠全双工终止连接
      • 假设在四次挥手过程中,最后一个ACK丢失了。被动关闭方会重发FIN,所以主动关闭方必须保存状态信息,以便重发最后一个ACK。
    2. 确保重复的报文在网络中消失
      • 假设两端之间的连接被关闭,不久之后又重新打开。TCP应当防止上次连接的包出现在新的连接中。因为2倍MSL的TIME_WAIT状态的存在,TCP不会立即开始新的连接。第一个MSL使数据包消失,第二个MSL使应答消失。
  • 相关阅读:
    9-16.复选框
    9-14.时间输入框,颜色选择器和文件域
    Safari的表格用col预定义宽度,配合table-layout:fixed.但是单元格仍会被撑开
    了解git
    统计对象的length
    对于数组的操作:splice与slice
    margin啥时候取较大值
    页面上clientTop,offsetTop,scrollTop的理解,js元素的event.x/.clientX等位置的理解
    ie下滚动时利用定位position改变元素位置会严重抖动
    npm安装包出现NO为4048的错误,一直提示说要用管理员身份登录
  • 原文地址:https://www.cnblogs.com/zyfgs2012/p/4065820.html
Copyright © 2020-2023  润新知