TCP学习笔记

来源:互联网 发布:webgis python 编辑:程序博客网 时间:2024/06/05 01:16

最近在想斗鱼弹幕应该如何抓取?然后百度,发现了这篇文章,(弹幕实现技术(后台)),里面有句“websocket,基于web的socket协议”,心想websocket是啥,好像大学用过,记不清了,百度websocket,就发现了这篇文章,websocket简介,然后里面讲到了“websocket协议是一种双向通信协议,它建立在TCP之上,同HTTP一样通过TCP来传输数据,但是它和HTTP最大的不同有两点。”HTTP是啥,TCP是啥?来,先复习一下TCP吧。

TCP协议,传输控制协议(Transmission Control Protocol),是一种面向连接的,可靠的,基于字节流传输层通信协议。

看到这里,想到了TCP/IP参考模型和OSI模型,这篇文章写的特别清楚,TCP/IP四层模型与OSI参考模型。
TCP/IP参考模型

  • 1、链路层(数据链路层/网络接口层):包括操作系统中的设备驱动程序、计算机中对应的网络接口卡
  • 2、网络层:处理分组在网络中的活动,比如分组的选路
  • 3、运输层:主要为两台主机上的应用提供端到端的通信
  • 4、应用层:负责处理特定的应用程序细节

网络层和运输层的区别:在TCP/IP协议族中,

  • 1、网络层IP提供的是一种不可靠的服务。它只是尽可能快地把分组从源节点送到目的节点,但不提供任何可靠性的保证。
  • 2、TCP在不可靠的IP层上,提供了一个可靠的运输层,为了提供这种可靠的服务,TCP采用了超时重传、发送端到接收端的确认分组等机制。

TCP通信需要经过创建连接、数据传送、终止连接三个步骤

TCP特点:

  • 面向连接
  • 基于数据流(字节流)
    • TCP缓冲区
    • 以TCP报文段的方式发送
  • 可靠传输:
    • TCP采用发送应答机制
    • 超时重传
    • 错误校验
    • 流量控制和阻塞管理

建立连接(三次连接)

  • 客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的段1
  • 服务器端回应客户端,是三次握手中的第2个报文段,同时带ACK标志和SYN标志。它表示对刚才客户端SYN的回应;同时又发送SYN给客户端,询问客户端是否准备好进行数据通讯
  • 客户端必须再次回应服务器端一个ACK报文,这是报文段3

数据传输

  • 客户端发出段4,包含数据
  • 服务端发出段5 ,对客户端发送的数据表示确认收到,并向客户端发送数据
  • 客户端发出段6,对服务端发送的数据表示确认收到

关闭连接(四次挥手)

  • 客户端发出段7,FIN位表示关闭连接的请求
  • 服务端发出段8,应答客户端的关闭连接请求
  • 服务端发出段9,其中也包含FIN位,向客户端发送关闭连接请求
  • 客户端发出段10,应答服务器的关闭连接请求

TCP程序流程
TCP程序流程

TCP服务器

import socket# TCP协议对应的为SOCK_STREAM流式server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 绑定ip和端口address = ("", 8000)server_sock.bind(address)# 让服务端的socket开启监听,等待客户端的连接请求# listen中的参数表示已经建立连接和半连接的总数server_sock.listen(128)# 使用accept方法接收客户端的连接请求# 如果有新的客户端来连接服务器,就产生一个新的套接字专门为这个客户端服务# client_sock用来为这个客户端服务,与客户端形成一对一的连接# 而server_sock就可以省下来等待其他新客户端的连接请求# client_addr是请求连接的客户端的地址信息,类型为元组,包含用户的ip和端口client_sock, client_addr = server_sock.accept()# recv()方法可以接收客户端发送过来的数据,指明最大收取1024个字节的数据recv_data = client_sock.recv(1024)# python3中收到的数据为bytes类型# 可以通过recv_data.decode()将bytes类型转为str类型print(recv_data.decode())# send()方法向客户端发送数据,要求发送bytes类型的数据client_sock.send("hello client".encode())# 关闭与客户端连接的socket# 只要这个套接字关闭了,就意味着不能再为这个客户端服务了,如果还需要服务,只能再次重新连接client_sock.close()# 关闭服务端的监听socket# 只要这个套接字关闭了,就意味着整个程序不能再接收任何新的客户端的连接server_sock.close()

TCP客户端

import socket# 创建客户端socket用以跟服务器连接通信# TCP协议对应为SOCK_STREAMclient_sock = socket.socket(socket.AF_INEF, socket.SOCK_STREAM)# connect方法用来连接服务器server_addr = ("127.0.0.1", 8000)client_sock.connect(server_addr)msg = input("请输入要发送的内容")# send()方法向服务器发送数据client_sock.send(msg.encode())# recv()接收对方发送过来的数据,最大接收1024个字节recv_data = client_sock.recv(1024)print(recv_data.decode())# 关闭客户端套接字client_sock.close()

2MSL(Maximum Segment Lifetime)TIME_WAIT状态的存在有两个理由:

  • 让4次挥手关闭流程更加可靠;4次挥手的最后一个ACK是由主动关闭方发送出去的,若这个ACK丢失,被动关闭方会再次发一个FIN过来。若主动方能够保持一个2MSL的TIME_WAIT状态,则有更大的机会让丢失的ACK被再次发送出去。
  • 防止lost duplicate对后续新建正常链接的传输造成破坏。

为了解决服务器socket可能的2MSL延迟问题,我们可以为服务器socket设置SO_REUSEADDR选项,如下:

# 1表示开启此选项功能,即开启重用地址功能server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

TCP长连接和短连接

TCP在真正的读写操作之前,server和client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立通过三次握手,释放则需要四次挥手,所以说每个连接的建立都是需要资源消耗和时间消耗的。

短连接的操作步骤是:
建立连接——数据传输——关闭连接….建立连接——数据传输——关闭连接

长连接的操作步骤是:
建立连接——数据传输….(保持连接)……数据传输——关闭连接

TCP长连接和短连接的优缺点以及应用场景:
长连接:

  • 优点:可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间
  • 缺点:client和server之间的连接如果一直不关闭的话,随着客户端连接越来越多,会造成服务器瘫痪
  • 应用场景:数据库的连接

短连接:

  • 优点:对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段
  • 缺点:如果客户端请求频繁,将会在TCP的建立和关闭操作上浪费时间和带宽
  • 应用场景:web网站的HTTP服务一般使用短连接
原创粉丝点击