zoukankan      html  css  js  c++  java
  • <<TCP/IP高效编程>>读书笔记

    技巧6:TCP是一种流协议

    TCP是一个流协议,跟流水一样,是没有边界的,也就是说如果B端第一次发送100个字节,第二次发送200个字节,当我们读取的时候,是根据缓冲区的大小来看读取结果的,如果我们缓冲区大于300,那么将会把全部读取出来,如果小于300,例如150,则会读取第一个和第二个的50个字节,这样需要我们去处理边界的问题,一般是通过加消息头来确定,而UDP则没有这个问题

    技巧9:TCP是个可靠的,但不是完全可靠的

    1.假设一个A主机TCP数据包发送给B主机,B主机成功收到,但是还没有复制到应用程序,这个时候B主机已经把ACK已经发给了发送A主机,A主机确认B主机已经接收到数据包,但是B注意在将数据复制到应用程序的时候,崩溃了,应用程序并没有收到数据包。TCP不能保证应用程序B主机收到所有数据,只能保证B主机收到的数据都是无损且按序的(据我所致TCP收到的数据也不能保证无损,因为TCP使用的校验机制不是个很好的算法)

    2.网线突然中断,TCP无法检测到,除非中间路由器发送一个ICMP报文,否则无法知道网络是否终端

    3.对方突然崩溃,但是自己的应用程序刚好阻塞了,比如A主机和B主机,A主机应用程序突然崩溃了,这个时候A主机发送FIN给B主机,但是B主机在执行fgets函数,被阻塞了,无法处理FIN

    技巧10:TCP不是轮询的

    TCP无法立即知道连接是否丢失(技巧9说的情况),这样做的原因:

    1.是减少网络带宽的耗费

    2.灵活,由应用程序来决定是否提供这个功能

    3.连接中断可能只是暂时的,比如可能通过查找另外一条路由器路径来修复连接终端的问题

    TCP有Keep-live机制,但是对于应用程序来说基本没什么用,主要是通过发送一个包给对方,如果对方收到会发送一个ack给本机,如果超过一定时间没回应则被认为网络中断(也可能要超过一定的次数没回应,BSD是9次没回应则是认为连接终端,两次发送间隔75秒)

    一般都是利用心跳来解决应用程序是否中断的问题,有时候会独立一个端口来使用心跳,这样做的好处是可以防止心跳消息与其他消息混杂一起,并且可以防止丢失(技巧6),<<UNIX网络编程>>21.5也有提供TCP紧急心跳的方法

    技巧16:

    shutdown(int fd,int how)

    how = 0:

    关闭连接的接收方,即不再接收数据,如果之后有接收数据的操作,则返回EOF

    how = 1:

    关闭发送方的连接,在将缓冲区的数据发送完以后,才会发送FIN给对方,在缓冲区发送完之前,写操作将错误,这个就是所谓的half  close

    how = 2:

    关闭双方的连接,即shutdown(fd,1)和shutdown(fd,2),但和close不同,shutdown并没有关闭套接字,也没有释放资源,close会减少sockfd的引用技术,只有当引用技术为0的时候对方才会收到FIN,而shutdown则能保证发送fin给对方

  • 相关阅读:
    P3350 [ZJOI2016]旅行者
    P4178 Tree
    P2375 [NOI2014]动物园
    P2827 蚯蚓
    1002: [FJOI2007]轮状病毒
    1070: [SCOI2007]修车
    AtCoder Grand Contest 021完整题解
    Running to the End(Codeforces & AtCoder 百套计划)
    SDWC2017游记
    非传统题初探——AtCoder Practice Contest #B
  • 原文地址:https://www.cnblogs.com/linyilong3/p/2994569.html
Copyright © 2011-2022 走看看