Python全栈(四)高级编程技巧之6.Socket编程-TCP客户端和服务端
文章目录
一、TCP介绍
1.概念
TCP协议,即传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
TCP通信模型中,在通信开始之前,一定要先建立相关连接,才能发送数据。
2.TCP特点:
- 面向连接:
通信双方必须先建立连接才能进行数据的传输。 - 可靠传输: TCP采用发送应答机制
- 超时重传:
启动定时器,在规定时间内未收到,则重新发送,直到收到。 - 错误校验
- 流量控制和阻塞管理
3.TCP和UDP的比较
- TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接.
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付.
- UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信。
- TCP对系统资源要求较多,UDP对系统资源要求较少。
- TCP严格区分客户端和服务端,UDP不一定区分。
UDP通信和TCP通信的过程如下:
UDP通信:
TCP通信:
形象地说:
UCP类比于写信,别人不一定能收到;
TCP类比于打电话,可以获知对方是否收到。
二、TCP客户端构建
客户端:是需要被服务的一方;
服务器端:就是提供服务的一方。
TCP客户端构建流程
- 创建socket
- 连接服务器
- 收发数据(最大接收2014个字节)
- 关闭套接字
NetAssist进行配置如下
此时,NetAssist作为服务端,Python运行作为客户端。
import socket def main(): #创建TCP套接字 tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #连接服务器 server_ip = input('Server IP:') server_port = int(input('Server Port:')) tcp_client.connect((server_ip,server_port)) #接收数据 recv_data = tcp_client.recv(1024) print(recv_data) #关闭套接字 tcp_client.close() if __name__ == '__main__': main()
显示
数据进行解码:
import socket def main(): #创建TCP套接字 tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #连接服务器 server_ip = input('Server IP:') server_port = int(input('Server Port:')) tcp_client.connect((server_ip,server_port)) #接收数据 recv_data = tcp_client.recv(1024).decode('gbk') print(recv_data) #关闭套接字 tcp_client.close() if __name__ == '__main__': main()
显示
增加发送数据:
import socket def main(): #创建TCP套接字 tcp_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #连接服务器 server_ip = input('Server IP:') server_port = int(input('Server Port:')) tcp_client.connect((server_ip,server_port)) #发送数据 send_data = input('Data to send:') tcp_client.send(send_data.encode('gbk')) #接收数据 recv_data = tcp_client.recv(1024).decode('gbk') print(recv_data) #关闭套接字 tcp_client.close() if __name__ == '__main__': main()
显示
三、TCP服务端构建流程
TCP服务端构建过程:
- socket创建套接字
- bind绑定IP和port
- listen使套接字变为可以被动连接
- accept等待客户端的连接
- recv/send接收发送数据
- 关闭套接字
NetAssist进行配置如下
此时,NetAssist作为客户端,Python运行作为服务器端;
在代码未运行时,NetAssist点击连接按钮连接不了,因为此时服务器端还未开启,应该先运行服务器端、再连接。
import socket def main(): #创建TCP监听套接字 tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #绑定信息 tcp_server.bind(('',7890)) #默认套接字主动变被动 tcp_server.listen(128) #等待,创建服务套接字 new_client_socket,client_addr = tcp_server.accept() print(client_addr) if __name__ == '__main__': main()
显示
TCP监听套接字负责等待新的客户端连接;
产生的服务套接字负责收发数据。
进一步完善代码:
import socket def main(): #创建TCP监听套接字 tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #绑定信息 tcp_server.bind(('',7890)) #默认套接字主动变被动 tcp_server.listen(128) #等待,创建服务套接字 new_client_socket,client_addr = tcp_server.accept() print(client_addr) #接收数据 recv_data = new_client_socket.recv(1024) print(recv_data.decode('gbk')) #发送数据 send_data = input('Data to send:').encode('gbk') new_client_socket.send(send_data) new_client_socket.close() tcp_server.close() if __name__ == '__main__': main()
显示
四、TCP服务端为多个客户端服务
1.代码分析
服务器端代码
tcp_server.accept()部分会阻塞,阻塞直到有客户端连接;
new_client_socket.recv()部分会阻塞,直到客户端有数据发送或者客户端断开连接解堵塞。
2.多客户端实现
import socket def main(): # 创建TCP监听套接字 tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定信息 tcp_server.bind(('', 7890)) #为多个客户端服务 while True: # 默认套接字主动变被动 tcp_server.listen(128) # 等待,创建服务套接字 new_client_socket, client_addr = tcp_server.accept() print(client_addr) # 接收数据 recv_data = new_client_socket.recv(1024) print(recv_data.decode('gbk')) # 发送数据 send_str = 'Hello, ' +client_addr[0] send_data = send_str.encode('gbk') new_client_socket.send(send_data) new_client_socket.close() tcp_server.close() if __name__ == '__main__': main()
显示
显然,此时可以连接多个客户端,但是每个客户端只能发送一次数据,再发送会产生异常,自动断开连接,要想多次服务,还需要进一步改进:
import socket def main(): # 创建TCP监听套接字 tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定信息 tcp_server.bind(('', 7890)) #为多个客户端服务 while True: # 默认套接字主动变被动 tcp_server.listen(128) # 等待,创建服务套接字 new_client_socket, client_addr = tcp_server.accept() print(client_addr) #为客户端提供多次服务 while True: # 接收数据 recv_data = new_client_socket.recv(1024) # 发送数据 if recv_data.decode('gbk'): print(recv_data.decode('gbk')) send_str = 'Hello, ' +client_addr[0] send_data = send_str.encode('gbk') new_client_socket.send(send_data) #无数据,退出循环,关闭连接 else: break new_client_socket.close() tcp_server.close() if __name__ == '__main__': main()
显示
易知,可以实现为多个客户端提供服务,但是一次只能为一个客户端提供服务,不能同时为多个客户端服务。
五、应用–文件下载器
TCP客户端实现思路:
- 创建套接字
- 连接服务器
- 获取下载文件名称
- 发送下载文件下载请求
- 接收服务端发送过来的数据
- 保存文件
- 关闭套接字
tcp_client.py:
import socket def main(): #创建套接字 tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 连接服务器 server_ip = input('Server IP:') server_port = int(input('Server Port:')) tcp_client_socket.connect((server_ip,server_port)) #获取下载文件名称 file_name = input('Input File Name:') #发送文件下载请求 tcp_client_socket.send(file_name.encode('gbk')) #接收文件 recv_data = tcp_client_socket.recv(1024*1024) #保存文件 with open('Received ' + file_name,'wb') as f: f.write(recv_data) #关闭套接字 tcp_client_socket.close() if __name__ == '__main__': main()
用NetAssist作服务器端,进行测试,结果
TCP服务器端实现思路:
- 创建套接字
- 绑定信息
- 主动变被动
- 等待客户端连接
- 收发数据
- 关闭套接字
tcp_server.py:
import socket def send_file_to_client(new_client_socket): file_name = new_client_socket.recv(1024).decode('gbk') try: with open(file_name,'rb') as f: content = f.read() new_client_socket.send(content) except: print('No such File:%s' % file_name) return def main(): # 创建TCP监听套接字 tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定信息 tcp_server.bind(('', 7890)) # 默认套接字主动变被动 tcp_server.listen(128) # 等待,创建服务套接字 new_client_socket, client_addr = tcp_server.accept() print(client_addr) # 给客户端返回文件内容 send_file_to_client(new_client_socket) #关闭客户端 new_client_socket.close() tcp_server.close() if __name__ == '__main__': main()
服务器端和客户端运行起来,可得结果:
显示生成新文件的动态过程:
易知,运行并连接后,在客户端输入文件名,服务器端读写本地文件并发给客户端进行保存生成Received test.py文件。
- 点赞 11
- 收藏
- 分享
- 文章举报
- Python全栈(四)高级编程技巧之11.Python全局解释器锁和高级编程技巧总结
- Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
- Python全栈(四)高级编程技巧之10.Python多任务-协程
- Python全栈(四)高级编程技巧之9.Python多任务-进程
- Python全栈(四)高级编程技巧之8.Python多任务-线程(下)和进程介绍
- Python全栈(四)高级编程技巧之7.Python多任务-线程的介绍和使用
- Python tcp编程,TCP服务端和TCP客户端代码编写
- Python 高级编程技巧
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
- python 批量执行脚本(服务端和客户端建立TCP连接)
- Python 高级编程技巧
- 关于 socket套接字编程 tcp服务端和客户端的建立
- Python高级编程技巧
- 网络编程,IP地址、端口、tcp、socket、TCP客户端,服务端和TCP多任务版服务端程序
- 猎豹MFC--Socket编程基础TCP服务端和客户端
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
- 网络编程--python实现 简单的服务端和客户端
- 项目实例:WebService axis1.4高级编程(服务端、客户端)
- python 的一些高级编程技巧
- Python高级编程技巧