基于 TCP 协议的简单套接字
3151 字
16 分钟
基于 TCP 协议的简单套接字
基于TCP协议的简单套接字(打电话模型)
【一】简单版1.0
服务端
# -*-coding: Utf-8 -*-# @File : 服务端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体# socket.SOCK_DGRAM : 报协议 ----> 每一次数据都是单独一部分phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用 ----> 服务器用# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)# 端口号:0-65535, 1024以前的都被系统保留使用# phone.bind(('ip', port))phone.bind(('127.0.0.1', 8080))
# 【3】.开机 -- 监听状态# 5 :指的是半连接池的大小phone.listen(5)print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080
# 【4】.等待电话链接请求:拿到电话链接 conn# 返回的是双向通路 --- 操作系统维持链接# conn : 双向通路的链接# client_addr : 客户端的iP和端口conn, client_addr = phone.accept()print('这是服务端的conn:>>>', conn)# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>print('这是服务端的client_addr:>>>', client_addr)# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)
# 【5】.接收消息# 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型data = conn.recv(1024)# 对接受的二进制数据进行解码print('从客户端接受的数据:>>>>', data.decode('utf-8'))# (5)从客户端接受的数据:>>>> is running for 发送信息# 发消息 返回消息状态等信息conn.send(data.upper())
# 【6】.关闭连接(必选的回收资源操作) conn# 完成后断开连接conn.close()
# 【7】.关机(可选操作)phone.close()客户端
# -*-coding: Utf-8 -*-# @File : 客户端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.拨通服务端电话# connect(('服务端ip', 服务端端口))phone.connect(('127.0.0.1', 8080))# (2)# 【3】.通信# send(二进制数据类型)phone.send('is running for 发送信息'.encode('utf8'))
# 接受服务端返回的数据data = phone.recv(1024)# 打印返回的消息 解码print(data.decode('utf8'))# (6)IS RUNNING FOR 发送信息
# 【4】.关闭连接(必选的回收资源操作)phone.close()上面的问题就是信息只能传输一次
【二】升级版2.0
加上通信循环
【1】版本2.1 - 通信循环结束条件
服务端
# -*-coding: Utf-8 -*-# @File : 服务端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体# socket.SOCK_DGRAM : 报协议 ----> 每一次数据都是单独一部分phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用 ----> 服务器用# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)# 端口号:0-65535, 1024以前的都被系统保留使用# phone.bind(('ip', port))phone.bind(('127.0.0.1', 8080))
# 【3】.开机 -- 监听状态# 5 :指的是半连接池的大小phone.listen(5)print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080
# 【4】.等待电话链接请求:拿到电话链接 conn# 返回的是双向通路 --- 操作系统维持链接# conn : 双向通路的链接# client_addr : 客户端的iP和端口conn, client_addr = phone.accept()print('这是服务端的conn:>>>', conn)# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>print('这是服务端的client_addr:>>>', client_addr)# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)
while True: # 【5】.接收消息 # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型 data = conn.recv(1024)
if data.decode('utf-8') == 'q': break
# 对接受的二进制数据进行解码 print('从客户端接受的数据:>>>>', data.decode('utf-8')) # (5)从客户端接受的数据:>>>> is running for 发送信息 # 发消息 返回消息状态等信息 conn.send(data.upper())
# 【6】.关闭连接(必选的回收资源操作) conn# 完成后断开连接conn.close()
# 【7】.关机(可选操作)phone.close()客户端
# -*-coding: Utf-8 -*-# @File : 客户端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.拨通服务端电话# connect(('服务端ip', 服务端端口))phone.connect(('127.0.0.1', 8080))# (2)
while True:
# 【3】.通信 # send(二进制数据类型) msg = input('请输入需要发送的消息:>>>>').strip()
phone.send(f'{msg}'.encode('utf8'))
# 加入结束条件强制结束通信 if msg == 'q': break
# 接受服务端返回的数据 data = phone.recv(1024) # 打印返回的消息 解码 print(data.decode('utf8')) # (6)IS RUNNING FOR 发送信息
# 【4】.关闭连接(必选的回收资源操作)phone.close()输入的信息为空时,会阻塞通信
阻塞在服务端的反馈信息位置
客户端的接受信息不能为空
【2】版本2.2 - 用户输入信息为空时阻塞
客户端
# -*-coding: Utf-8 -*-# @File : 客户端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.拨通服务端电话# connect(('服务端ip', 服务端端口))phone.connect(('127.0.0.1', 8080))# (2)
while True:
# 【3】.通信 # send(二进制数据类型) msg = input('请输入需要发送的消息:>>>>').strip()
phone.send(f'{msg}'.encode('utf8'))
if len(msg) == 0: continue # 加入结束条件强制结束通信 if msg == 'q': break
# 接受服务端返回的数据 data = phone.recv(1024) # 打印返回的消息 解码 print(data.decode('utf8')) # (6)IS RUNNING FOR 发送信息
# 【4】.关闭连接(必选的回收资源操作)phone.close()服务端
# -*-coding: Utf-8 -*-# @File : 服务端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体# socket.SOCK_DGRAM : 报协议 ----> 每一次数据都是单独一部分phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用 ----> 服务器用# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)# 端口号:0-65535, 1024以前的都被系统保留使用# phone.bind(('ip', port))phone.bind(('127.0.0.1', 8080))
# 【3】.开机 -- 监听状态# 5 :指的是半连接池的大小phone.listen(5)print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080
# 【4】.等待电话链接请求:拿到电话链接 conn# 返回的是双向通路 --- 操作系统维持链接# conn : 双向通路的链接# client_addr : 客户端的iP和端口conn, client_addr = phone.accept()print('这是服务端的conn:>>>', conn)# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>print('这是服务端的client_addr:>>>', client_addr)# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)
while True: # 【5】.接收消息 # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型 data = conn.recv(1024)
if data.decode('utf-8') == 'q': break
# 对接受的二进制数据进行解码 print('从客户端接受的数据:>>>>', data.decode('utf-8')) # (5)从客户端接受的数据:>>>> is running for 发送信息 # 发消息 返回消息状态等信息 conn.send(data.upper())
# 【6】.关闭连接(必选的回收资源操作) conn# 完成后断开连接conn.close()
# 【7】.关机(可选操作)phone.close()客户端强制终止程序时,服务端会产生一系列问题
【3】版本2.3 - 用户信息为空时检测异常
- 客户端
# -*-coding: Utf-8 -*-# @File : 客户端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.拨通服务端电话# connect(('服务端ip', 服务端端口))phone.connect(('127.0.0.1', 8080))# (2)
while True:
# 【3】.通信 # send(二进制数据类型) msg = input('请输入需要发送的消息:>>>>').strip()
phone.send(f'{msg}'.encode('utf8'))
if len(msg) == 0: continue # 加入结束条件强制结束通信 if msg == 'q': break
# 接受服务端返回的数据 data = phone.recv(1024) # 打印返回的消息 解码 print(data.decode('utf8')) # (6)IS RUNNING FOR 发送信息
# 【4】.关闭连接(必选的回收资源操作)phone.close()- 服务端
# -*-coding: Utf-8 -*-# @File : 服务端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体# socket.SOCK_DGRAM : 报协议 ----> 每一次数据都是单独一部分phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用 ----> 服务器用# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)# 端口号:0-65535, 1024以前的都被系统保留使用# phone.bind(('ip', port))phone.bind(('127.0.0.1', 8080))
# 【3】.开机 -- 监听状态# 5 :指的是半连接池的大小phone.listen(5)print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080
# 【4】.等待电话链接请求:拿到电话链接 conn# 返回的是双向通路 --- 操作系统维持链接# conn : 双向通路的链接# client_addr : 客户端的iP和端口conn, client_addr = phone.accept()print('这是服务端的conn:>>>', conn)# (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)>print('这是服务端的client_addr:>>>', client_addr)# (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)
while True: # 【5】.接收消息 # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型 try: data = conn.recv(1024)
if len(data) == 0: # 在 unix 系统里,一旦data收到的内容为空 # 就意味着一种异常行为:客户端非法断开了链接 break
if data.decode('utf-8') == 'q': break
# 对接受的二进制数据进行解码 print('从客户端接受的数据:>>>>', data.decode('utf-8')) # (5)从客户端接受的数据:>>>> is running for 发送信息 # 发消息 返回消息状态等信息 conn.send(data.upper()) except Exception as e: break
# 【6】.关闭连接(必选的回收资源操作) conn# 完成后断开连接conn.close()
# 【7】.关机(可选操作)phone.close()【三】迭代版3.0
- 服务端应该满足的特点
- 服务端一直提供服务
- 在建立连接与结束链接之间再加上一层 循环
- 服务端并发提供服务
- 服务端一直提供服务
【1】3.1 - 链接循环(循环建立链接)
- 客户端
# -*-coding: Utf-8 -*-# @File : 客户端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.拨通服务端电话# connect(('服务端ip', 服务端端口))phone.connect(('127.0.0.1', 8080))# (2)
while True:
# 【3】.通信 # send(二进制数据类型) msg = input('请输入需要发送的消息:>>>>').strip()
phone.send(f'{msg}'.encode('utf8'))
if len(msg) == 0: continue # 加入结束条件强制结束通信 if msg == 'q': break
# 接受服务端返回的数据 data = phone.recv(1024) # 打印返回的消息 解码 print(data.decode('utf8')) # (6)IS RUNNING FOR 发送信息
# 【4】.关闭连接(必选的回收资源操作)phone.close()- 服务端
# -*-coding: Utf-8 -*-# @File : 服务端 .py# author: Chimengmeng# blog_url : https://www.cnblogs.com/dream-ze/# Time:2023/6/20import socket
# 【1】.买手机# socket.SOCK_STREAM :流式协议 ----> TCP协议 ----> 所有数据是一个整体# socket.SOCK_DGRAM : 报协议 ----> 每一次数据都是单独一部分phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 【2】.绑定手机卡 ---> 192.168.1.50(本机IP地址)# 0.0.0.0(任意IP地址) ---> 关联公网IP才会起作用 ----> 服务器用# 127.0.0.1(本机固定IP地址) ---> 只有本机才能访问这个地址(测试用)# 端口号:0-65535, 1024以前的都被系统保留使用# phone.bind(('ip', port))phone.bind(('127.0.0.1', 8080))
# 【3】.开机 -- 监听状态# 5 :指的是半连接池的大小phone.listen(5)print(f'服务器启动,开始监听ip:>>>{"127.0.0.1"},port:>>>{8080}')# (1)服务器启动,开始监听ip:>>>127.0.0.1,port:>>>8080
# 【4】.等待电话链接请求:拿到电话链接 conn# ---- 加上链接循环 ----> 循环建链接while True: # 返回的是双向通路 --- 操作系统维持链接 # conn : 双向通路的链接 # client_addr : 客户端的iP和端口 conn, client_addr = phone.accept() # (3)这是服务端的conn:>>> <socket.socket fd=352, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 5249)> print('这是服务端的client_addr:>>>', client_addr) # (4)这是服务端的client_addr:>>> ('127.0.0.1', 5249)
while True: # 【5】.接收消息 # 1024 :最大接受的数据量为1024 bytes类型,收到的是bytes类型 try: data = conn.recv(1024)
if len(data) == 0: # 在 unix 系统里,一旦data收到的内容为空 # 就意味着一种异常行为:客户端非法断开了链接 break
if data.decode('utf-8') == 'q': break
# 对接受的二进制数据进行解码 print('从客户端接受的数据:>>>>', data.decode('utf-8')) # (5)从客户端接受的数据:>>>> is running for 发送信息 # 发消息 返回消息状态等信息 conn.send(data.upper()) except Exception as e: break
# 【6】.关闭连接(必选的回收资源操作) conn # 完成后断开连接 conn.close()
# 【7】.关机(可选操作)phone.close()支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
C 语言开发环境的安装与配置
编程语言在 Windows、Linux 与 macOS 上安装 C 工具链,配置编辑器,并编译运行第一个 C 程序。
2
C 语言基础:注释、关键字、变量与数据类型
编程语言学习 C 语言的注释、关键字、标识符、常量、变量和基本数据类型等基础知识。
3
C 语言发展史
编程语言了解 C 语言从 BCPL、B 语言到现代标准 C 的发展历程、核心特点与应用领域。
4
C 语言初识:程序运行机制与基本结构
编程语言认识 C 程序从源代码到运行的完整流程,以及基础语法和程序的基本结构。
5
C 语言数据类型
编程语言理解 C 语言的数据类型体系,包括基本类型、整数类型、浮点类型和逻辑类型。
随机文章随机推荐














