一、传输层**
该层为两台主机上的应用程序提供端到端的通信。传输层有两个传输协议:TCP(传输控制协议)和 UDP(用户数据报协议)。其中,TCP是一个可靠的面向连接的协议,udp是不可靠的或者说无连接的协议。
二、TCP的特点:
TCP是面向运输层的协议。使用TCP协议之前,必须先建立TCP连接,在传输完成后,必须释放已经建立的TCP连接。
每条TCP连接只能有两个端,每一条TCP连接只能是点对点的。
TCP提供可靠的交付的服务。通过TCP连接传输的数据,无差错、不丢失、不重复,并且按序到达。
TCP提供全双工通信。TCP通信允许通信双发的任何时候都能发送数据。
TCP面向字节流。
三、TCP的连接
每一条TCP连接都有两个端点,TCP连接的端点叫做套接字(socket)或 插口。
套接字(socket)=(IP地址:端口号)
每一条TCP连接唯一的被通信两端的端点(即两个套接字)所确定,即:TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}
代码端
服务端
import socket import threading client_flag=0 #定义一个标志位 def client1(socket_tcp_server): #采用了多线程 global client_flag #声明该变量可以在该方法使用 # accept等待客户端连接 # 如果有新的客户来连接服务器,那么就产生一个新的套接字连接客户端服务 # new_client_socket用来为这个客户端服务 # socket_tcp_server就可以省下专门等待其他客户连接 new_client_socket, client_addr = socket_tcp_server.accept() #当服务器得到客户端请求连接时,client_flag=1 client_flag=1 print("客户端连接成功",client_addr) while True: # 接收数据 recv_date = new_client_socket.recv(1024) # 当客户端断开连接时,recv_date的值为空 if recv_date: #使服务器能一直收到信息,只有客户端断开时,才退出循环 print("client"+str(client_addr[1]%10000%1000%100%10)+":接收到的数据为:", recv_date.decode("gbk")) else: break #发送数据 send_date = "收到" new_client_socket.send(send_date.encode("gbk")) new_client_socket.close() #关闭这个套接字 print("对方已经结束了会话,等待新的连接") def main(): global client_flag socket_tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义一个监听套接字 socket_addr=("",7777) socket_tcp_server.bind(socket_addr) #服务器绑定一个端口 socket_tcp_server.listen(128) # listen使套接字转变为被动连接,即类似等待客户端连接,而不是主动虚招客户端 print("等待一个新客户端连接....") client1_threading = threading.Thread(target=client1, args=(socket_tcp_server,)) client1_threading.start() while True: if client_flag: #当client_flag为1时,即服务器得到客户端请求连接时,开始一个新的线程 client1_threading = threading.Thread(target=client1,args=(socket_tcp_server,)) #新建一个线程 client1_threading.start() #开启这个线程 client_flag = 0 #标志为,目的使线程不会一直增多,只有当服务器得到客户端请求连接时,才开始一个新的线程 if __name__ =='__main__': main()
客户端
import socket import threading def send_date(socket_tcp_client): #发送数据 while True: server_date = input() # 3.发送信息 if server_date == "exit": #当输入exit时,断开于服务器的连接 break else: socket_tcp_client.send(server_date.encode("gbk")) #发数据,enconde为编码 gbk为编码方式 socket_tcp_client.close() #关闭套接字 def recv_date(socket_tcp_client): #接收数据 while True: recv_date = socket_tcp_client.recv(1024) #接收信息,每次最大为1024 print("接收到的数据为:", recv_date.decode("gbk")) #decode为解码,gbk为解码方式 print("请输入要发送的数据:",end=" ") def main(): socket_tcp_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建一个套接字 server_ip=input("请输入服务器的IP:") server_port=int(input("请输入服务器的port:")) print("请输入要发送的数据,输入exit退出会话:",end=" ") server_addr=(server_ip,server_port) socket_tcp_client.connect(server_addr)# 2.绑定连接 send_tcp_date=threading.Thread(target=send_date,args=(socket_tcp_client,)) #定义两个线程,分别为发送和接收 recv_tcp_date=threading.Thread(target=recv_date,args=(socket_tcp_client,)) send_tcp_date.start() recv_tcp_date.start() #开启这两个线程 if __name__ =='__main__': main()
测试:可以用pycharm运行一个服务器,再运行多个客户端测试,也可以把服务器代码放入虚拟机中。也可以用网络调试助手测试。
参考地址:https://blog.csdn.net/weixin_44636409/article/details/115797806
标签:socket,python,TCP,server,client,tcp,date,客户端 From: https://www.cnblogs.com/ckfuture/p/16845467.html