python代码实现tcp客户端和服务端通信演示

1.TCP介绍

TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。TCP通信需要经过创建连接、数据传送、终止连接三个步骤。

2.TCP特点

1. 面向连接

通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。双方间的数据传输都可以通过这一个连接进行。完成数据交换后,双方必须断开此连接,以释放系统资源。

这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。

2. 可靠传输

1)TCP采用发送应答机制

TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功

2)超时重传

发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。

TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。

3)错误校验

TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。

4) 流量控制和阻塞管理

流量控制用来避免主机发送得过快而使接收方来不及完全收下。

3.TCP的通信架构

udp通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话"

4.python代码实现TCP客户端发送,接收数据通信

TCP通信与UDP的很大不同就是首先要建立连接,然后才能进行通信,数据的传输。如下创建TCP客户端。

from socket import *
# 1.创建套接字

tcp_socket = socket(AF_INET,SOCK_STREAM)

# 2.准备连接服务器,建立连接
serve_ip = input("请输入服务器ip:")
serve_port = int(input("请输入对应的端口号:"))  # 端口要是int类型,所有要转换

tcp_socket.connect((serve_ip,serve_port))  # 连接服务器,建立连接,参数是元组形式

# 3.准备需要传送的数据
send_data = input("请输入要发送的数据:")
tcp_socket.send(send_data.encode("gbk"))  #用的是send方法,不是sendto

#4.从服务器接收数据
tcp_remsg = tcp_socket.recv(1024) #注意这个1024byte,大小根据需求自己设置
print(tcp_remsg.decode("gbk"))  #如果要乱码可以使用tcp_remsg.decode("gbk")

#4.关闭连接
tcp_socket.close()

上面创建TCP客户端后,使用网络调试助手,开启TCP Server模式,将其当成服务器,启动。

注意,服务器必须先启动,否则报错,无法建立连接

5.TCP实现服务器

想要完成一个tcp服务器的功能,需要的流程如下:

  1. socket创建一个套接字
  2. bind绑定ip和port
  3. listen使套接字变为可以被动链接
  4. accept等待客户端的链接
  5. recv/send接收发送数据
from socket import  *

# 1.创建套接字
tcp_server = socket(AF_INET,SOCK_STREAM)

# 2.绑定ip,port
address = ('',3434)
tcp_server.bind(address)

# 3.启动被动连接
# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
tcp_server.listen(128)  #这个值主要决定了同一时刻有多少个客户端可以连接

# 4.创建接收
# 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务
# client_socket用来为这个客户端服务,相当于的tcp_server套接字的代理
# tcp_server_socket就可以省下来专门等待其他新客户端的链接
# 这里clientAddr存放的就是连接服务器的客户端地址
client_socket, clientAddr = tcp_server.accept()


#5.接收对方发送过来的数据
recv_msg = client_socket.recv(1024)#接收1024给字节,这里recv接收的不再是元组,区别UDP
print("打印接收的数据:",recv_msg)
#6.发送数据给客户端
send_data = client_socket.send("这是给您的回复".encode("gbk"))

#7.关闭套接字
#关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连
client_socket.close()

 测试结果下,使用网络调试助手,配置称客户端,连接服务器通信

  1. tcp服务器一般情况下都需要绑定,否则客户端找不到这个服务器
  2. tcp客户端一般不绑定,因为是主动链接服务器,所以只要确定好服务器的ip、port等信息就好,本地客户端可以随机
  3. tcp服务器中通过listen可以将socket创建出来的主动套接字变为被动的,这是做tcp服务器时必须要做的
  4. 当客户端需要链接服务器时,就需要使用connect进行链接,udp是不需要链接的而是直接发送,但是tcp必须先链接,只有链接成功才能通信
  5. 当一个tcp客户端连接服务器时,服务器端会有1个新的套接字,这个套接字用来标记这个客户端,单独为这个客户端服务
  6. listen后的套接字是被动套接字,用来接收新的客户端的链接请求的,而accept返回的新套接字是标记这个新客户端的
  7. 关闭listen后的套接字意味着被动套接字关闭了,会导致新的客户端不能够链接服务器,但是之前已经链接成功的客户端正常通信。
  8. 关闭accept返回的套接字意味着这个客户端已经服务完毕
  9. 当客户端的套接字调用close后,服务器端会recv解堵塞,并且返回的长度为0,因此服务器可以通过返回数据的长度来区别客户端是否已经下线

统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。

发布了248 篇原创文章 · 获赞 1600 · 访问量 267万+

猜你喜欢

转载自blog.csdn.net/qq_26442553/article/details/94451871