热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

010Pythonsocket编程

客户端服务器的架构物理层:网卡,光缆,双绞线数据链路层:包含源mac地址和目标的mac地址,通过广播通讯网络层

客户端/服务器的架构

物理层:网卡,光缆,双绞线

数据链路层:包含源mac地址和目标的mac地址,通过广播通讯

网络层:跑的IP协议,IP地址可以定义到一个子网;通过ARP协议可以解析为mac地址;

传输层:提供端口 0-65535 TCP/UDP基于端口传输的

====》socket抽象层{抽象一堆接口,只要遵循socket标准,就支持TCP/UDP基于端口传输}

应用层:软件

客户端与服务端的连接:

1.服务端连接关键字注释:

import socketserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯
server.bind(("127.0.0.1", 8080)) # 开启 绑定IP以及端口
server.listen(5) # 监听;进程池的大小5# conn 三次握手建立的连接, addr 客户端地址 端口
conn, addr = server.accept()
print("TCP 的链接", conn)
print("客户端的地址和端口", addr)# conn.recv 接收消息;1024 代表接收到 1024个字节 (二进制格式) secv
data = conn.recv(1024)
print("来自于客户端的消息: %s" % data) # 打印输出内容# 发消息 给 客户端 send (将接收的消息转换为大写返回给客户端 二进制)
conn.send(data.upper())conn.close() # 关闭连接
server.close() # 结束套接字

2.客户端连接关键字注释:

import socketclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯
client.connect(("127.0.0.1", 8080)) # 与服务端进行连接;
client.send("Hello".encode("utf-8")) # 客户端发消息给 服务端 send 需要二进制 encode# 客户端收取 服务端发过来的消息
data = client.recv(1024)
print("来自于服务端的数据:%s" % data)client.close() # 关闭客户端

输出内容:

# 服务端内容:
TCP 的链接
客户端的地址和端口 ('127.0.0.1', 61799)
来自于客户端的消息: b'Hello'# 客户端内容:
来自于服务端的数据:b'HELLO'

解决粘包问题:

1.服务端解决粘包问题:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2017/3/4import socket
import subprocess # 远程执行命令模块
import structserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 重用ip和端口,在绑定IP 端口之前 bind 之前
server.bind(("127.0.0.1", 8080)) # 开启 绑定IP以及端口
server.listen(5) # 监听;进程池的大小5while True: # 循环连接 循环# conn 三次握手建立的连接, addr 客户端地址 端口conn, addr = server.accept()print("客户端地址:", addr)while True: # 消息传输 循环# conn.recv 接收消息;1024 代表接收到 1024个字节 (二进制格式) secvtry: # 捕捉异常cmd = conn.recv(1024) # recv 会导致堵塞if not cmd:break # 针对Linux 客户端断开后 进入死循环现象;print("来自于客户端的消息: %s" % cmd) # 打印输出内容# 发消息 给 客户端 send (将接收的消息转换为大写返回给客户端 二进制)res = subprocess.Popen(cmd.decode("utf-8"), # 使用 utf-8 解码shell=True, # 使用shell 解析stdout=subprocess.PIPE, # 标准输出定向到 管道stderr=subprocess.PIPE) # 标准错误输出 定向到 管道err = res.stderr.read()if err:back_msg = errelse:back_msg = res.stdout.read()#####解决粘包部分#####conn.send(struct.pack("i", len(back_msg))) # 计算出 返回值的长度conn.sendall(back_msg) # sendall将数据循环的返回 将得到的数据 输出返回
#####↑↑↑↑↑↑↑↑↑↑↑#####except Exception: # 如果发现 异常,直接breakbreakconn.close() # 关闭连接
server.close() # 结束套接字

2.客户端解决粘包问题

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2017/3/4import socket
import structclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯client.connect(("127.0.0.1", 8080)) # 与服务端进行连接;while True:cmd = input("输入你的命令:").strip()if not cmd:continueclient.send(cmd.encode("utf-8"))
#####解决粘包部分#####data = client.recv(4)data_size = struct.unpack("i", data)[0]recv_size = 0 # 收取数据的尺寸recv_bytes = b"" # 收到的bytes 用于拼接while recv_size #####↑↑↑↑↑↑↑↑↑↑↑#####print(recv_bytes.decode("gbk"))

当返回值过大时,通过自定义报头方式解决粘包

1.自定义报头,发送方服务端配置

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2017/3/4import socket
import subprocess # 远程执行命令模块
import struct
import jsonserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 重用ip和端口,在绑定IP 端口之前 bind 之前
server.bind(("127.0.0.1", 8080)) # 开启 绑定IP以及端口
server.listen(5) # 监听;进程池的大小5while True: # 循环连接 循环# conn 三次握手建立的连接, addr 客户端地址 端口conn, addr = server.accept()print("客户端地址:", addr)while True: # 消息传输 循环# conn.recv 接收消息;1024 代表接收到 1024个字节 (二进制格式) secvtry: # 捕捉异常cmd = conn.recv(1024) # recv 会导致堵塞if not cmd:break # 针对Linux 客户端断开后 进入死循环现象;print("来自于客户端的消息: %s" % cmd) # 打印输出内容# 发消息 给 客户端 send (将接收的消息转换为大写返回给客户端 二进制)res = subprocess.Popen(cmd.decode("utf-8"), # 使用 utf-8 解码shell=True, # 使用shell 解析stdout=subprocess.PIPE, # 标准输出定向到 管道stderr=subprocess.PIPE) # 标准错误输出 定向到 管道err = res.stderr.read()if err:back_msg = errelse:back_msg = res.stdout.read()
# ########将返回长度记录到字典当中,分三次将所有数据发出# 制作字典head_dic = {"data_size": len(back_msg)}head_json = json.dumps(head_dic) # 将字典依照 json 格式存储head_bytes = head_json.encode("utf-8") # 将json 格式 解码为 二进制bytes格式conn.send(struct.pack("i", len(head_bytes))) # 第一次发:将计算的报头head_bytes长度发送给客户端conn.send(head_bytes) # 第二次发:发送报头的数据conn.sendall(back_msg) # 第三次发:sendall将数据循环的返回 将得到的数据 输出返回except Exception: # 如果发现 异常,直接breakbreak
# ######↑↑↑↑↑↑↑↑↑↑↑↑↑conn.close() # 关闭连接
server.close() # 结束套接字

2.自定义报头,接收客户端配置

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2017/3/4import socket
import struct
import jsonclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 基于网络通信,是TCP协议的通讯
client.connect(("127.0.0.1", 8080)) # 与服务端进行连接;while True:cmd = input("输入你的命令:").strip()if not cmd:continueclient.send(cmd.encode("utf-8"))# 收取 服务端返回的数据:分三次收取# 1.收报头的长度head = client.recv(4) # 收取报头 二进制格式"b'\x11\x00\x00\x00'"head_size = struct.unpack("i", head)[0] # 取出报头长度 int "17"# 2.收报头:根据报头的长度head_bytes = client.recv(head_size) # 根据报头长度head_size 收取报头 二进制格式"b'{"data_size": 61}'"head_json = head_bytes.decode("utf-8") # 将bytes的格式解码为 json的字符串 "'str'{"data_size": 61}"head_dic = json.loads(head_json) # 将json字符串转换为 字典 "'dict'{'data_size': 61}"data_size = head_dic["data_size"] # 取出真实数据的长度 "61"# 3.根据长度-收取真实数据recv_size = 0 # 收取数据的尺寸recv_bytes = b"" # 收到的bytes 用于拼接while recv_size

转:https://www.cnblogs.com/baolin2200/p/6529926.html



推荐阅读
  • 利用 Python Socket 实现 ICMP 协议下的网络通信
    在计算机网络课程的2.1实验中,学生需要通过Python Socket编程实现一种基于ICMP协议的网络通信功能。与操作系统自带的Ping命令类似,该实验要求学生开发一个简化的、非标准的ICMP通信程序,以加深对ICMP协议及其在网络通信中的应用的理解。通过这一实验,学生将掌握如何使用Python Socket库来构建和解析ICMP数据包,并实现基本的网络探测功能。 ... [详细]
  • 【重识云原生】第四章云网络4.8.3.2节——Open vSwitch工作原理详解
    2OpenvSwitch架构2.1OVS整体架构ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-basedswitchin ... [详细]
  • UML 包图
    什么是包包可直接理解为命名空间,文件夹,是用来组织图形的封装,包图可以用来表述功能组命名空间的组织层次。•在面向对象软件开发的视角中&#x ... [详细]
  • MicrosoftDeploymentToolkit2010部署培训实验手册V1.0目录实验环境说明3实验环境虚拟机使用信息3注意:4实验手册正文说 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • TCP三次握手过程详解与图示解析
    本文详细解析了TCP三次握手的过程,并通过图示清晰展示了各个状态的变化。同时,文章还介绍了四次挥手的图解,解释了在TIME_WAIT状态中,客户端最后一次发送的ACK包的作用和重要性。 ... [详细]
  • 网宿科技正式宣布全面兼容最新QUIC (HTTP/3)协议标准
    网宿科技正式宣布全面兼容最新QUIC (HTTP/3)协议标准 ... [详细]
  • ——pun的配置,以及实现头盔以及两个手柄的同步。下载完pun并导入后如图所示有这些东西,pun的介绍还是很清楚的,有很多demo可以学习,而且文档自带。很容易上手。首先,就是服务器的配置了。 ... [详细]
  • 1、TCPIP 是个协议组,从下往上可分为:网络接口层、网络层、传输层和应用层。 在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP ... [详细]
  • 公司有个系统,比较古老,web端使用的是applet,applet作为socketclient端。另一台服务器运行socketserver.当多次执行某一个特定事务时(通过Applet,该事务会触 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • 端口转发(Port Forwarding)类似于服务重定向,许多路由器中也称其为虚拟服务器(Virtual Server)。通过合理配置端口转发,可以实现外部网络对内部网络中特定设备和服务的高效访问,从而提高通信效率和灵活性。此外,正确设置端口转发还能增强网络安全,确保只有授权的流量能够进入内网,有效防止未授权访问和潜在威胁。 ... [详细]
author-avatar
爱吃肉肉的狼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有