day08 多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤:


动态导入模块:
实践:
1 lib下的aa
def test():
print("hehe")
class C(object):
name = "yang"
def __init__(self):
self.name = 'shenyang' lib外的test
import importlib
dd = importlib.import_module('lib.aa')
dd.test()
print(dd.C().name)
运行:
判断错误
和 if 判断 一样 但是更简洁,一句话就OK
继续socket 编程:
#!/usr/bin/env python3
# Author: Shen Yang
import socket,os
ip_address = '192.168.16.10'
port = 8888
bind_address = (ip_address,port)
server = socket.socket()
server.bind(bind_address)
server.listen()
while True:
conn,addr = server.accept()
while True:
data = conn.recv(1024).decode()
if not data:
print("丢失连接")
break
print("这是来自",addr,data)
cmd_res = os.popen(data).read()
conn.send(str(len(cmd_res.encode('utf-8'))).encode('utf-8'))
conn.send(cmd_res.encode('utf-8'))
server.close()
客户端
#!/usr/bin/env python3
# Author: Shen Yang
import socket
ip_address = '192.168.16.10'
# ip_address = '192.168.81.133'
port = 8888
conn_address = (ip_address,port)
client = socket.socket()
client.connect(conn_address)
while True:
cmd = input(":> ").encode('utf-8')
if len(cmd) == 0:
continue
client.send(cmd)
cmd_size = int(client.recv(1024).decode())
print(cmd_size)
recov_size = 0
recov_data = b''
while recov_size < cmd_size:
data = client.recv(1024)
#print(data)
recov_size += len(data)
#print(recov_size)
recov_data += data
else:
print("收完了,大小",recov_size)
print(recov_data.decode())
client.close()
上面的代码 在linux 发送 会出现粘包 客户端收到的是两个数据
客户端加发送过程:
#!/usr/bin/env python3
import socket,os
ip_address = '192.168.81.133'
port = 8888
bind_address = (ip_address,port)
server = socket.socket()
server.bind(bind_address)
server.listen()
while True:
conn,addr = server.accept()
while True:
data = conn.recv(1024).decode()
if not data:
print("丢失连接")
break
print("这是来自",addr,data)
cmd_res = os.popen(data).read()
conn.send(str(len(cmd_res.encode('utf-8'))).encode('utf-8'))
ack = conn.recv(1024).decode()
print(ack)
conn.send(cmd_res.encode('utf-8'))
server.close()
ssh_client
#!/usr/bin/env python3
import socket
ip_address = '192.168.81.133'
port = 8888
conn_address = (ip_address,port)
client = socket.socket()
client.connect(conn_address)
while True:
cmd = input(":> ").encode('utf-8')
if len(cmd) == 0:
continue
client.send(cmd)
cmd_size = int(client.recv(1024).decode())
print(cmd_size)
client.send("收到大小".encode('utf-8'))
recov_size = 0
recov_data = b''
while recov_size < cmd_size:
data = client.recv(1024)
#print(data)
recov_size += len(data)
#print(recov_size)
recov_data += data
else:
print("收完了,大小",recov_size)
print(recov_data.decode())
client.close()
使用 os.stat 获取文件详细信息,发送给客户端
另外一个解决粘包的方法:
只收指定大小的数据 永远不可能粘包
#!/usr/bin/env python3
import socket,os,hashlib
ip_address = '192.168.81.133'
port = 8888
bind_address = (ip_address,port)
server = socket.socket()
server.bind(bind_address)
server.listen()
while True:
conn,addr = server.accept()
while True:
print("等待新链接")
data = conn.recv(1024)
if not data:
print("丢失连接")
break
print("这是来自",addr,data)
cmd,file_name = data.decode().split()
if os.path.isfile(file_name):
m = hashlib.md5()
f = open(file_name,'rb')
file_size = os.stat(file_name).st_size
conn.send(str(file_size).encode())
ack = conn.recv(1024).decode()
print("确认:",ack)
for line in f:
m.update(line)
print("sending...")
conn.send(line)
f.close()
conn.send(m.hexdigest().encode())
print("发送完毕")
server.close()
ftp_client.py
#!/usr/bin/env python3
import socket,hashlib
ip_address = '192.168.81.133'
port = 8888
conn_address = (ip_address,port)
client = socket.socket()
client.connect(conn_address)
while True:
cmd = input("input your cmd:> ").strip()
if len(cmd) == 0:
continue
if cmd.startswith("get"):
client.send(cmd.encode('utf-8'))
file_name = cmd.split()[1]
server_response = client.recv(1024)
print("收到回应:",server_response)
client.send("收到".encode('utf-8'))
total_file_size = int(server_response.decode())
print("总的",total_file_size)
f = open(file_name + '.new','wb')
recov_file_size = 0
m = hashlib.md5()
while recov_file_size < total_file_size:
if total_file_size - recov_file_size > 1024:
size = 1024
else:
size = total_file_size - recov_file_size
print("最后收",size)
#print("收数据...")
data = client.recv(size)
m.update(data)
recov_file_size += len(data)
f.write(data)
else:
print("收完了,大小",recov_file_size,total_file_size)
f.close()
print("服务器端发送的原MD5",client.recv(1024).decode())
print("自己算出来的最终MD5",m.hexdigest())
client.close()

继承关系:
创建socket server 步骤:
下面是重写的handle:
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
self.data = self.request.recv(1024).strip()
print("来自",self.client_address)
print(self.data)
self.request.send(self.data.upper())
except ConnectionResetError as e:
print("客户端退出",e)
break
if __name__ == "__main__":
HOST,PORT="localhost",9999
server = socketserver.TCPServer((HOST,PORT),MyTCPHandler)
server.serve_forever()
client:
import socket
client = socket.socket() #声明socket类型,同时生成socket连接对象
#client.connect(('192.168.16.200',9999))
client.connect(('localhost',9999))
while True:
msg = input(">>:").strip()
if len(msg) == 0:continue
client.send(msg.encode("utf-8"))
data = client.recv(10240)
print("recv:",data.decode())
client.close()

2 使用多进程实现: (windos 下不行,不支持,但是linux 绝得好使)

2 处理单个请求,一般也用不到
3 一直收请求,直到收到一个明确的shutdown (每0.5秒检测是否给我发了shutdown 的信号)
4 告诉 server_forever() 关闭
5 地址的重用,不需要等待tcp断开
day08 多线程socket 编程,tcp粘包处理的更多相关文章
- socket编程 TCP 粘包和半包 的问题及解决办法
一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次 ...
- Socket编程--TCP粘包问题
TCP是个流协议,它存在粘包问题 产生粘包的原因是: TCP所传输的报文段有MSS的限制,如果套接字缓冲区的大小大于MSS,也会导致消息的分割发送. 由于链路层最大发送单元MTU,在IP层会进行数据的 ...
- python/socket编程之粘包
python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...
- Python全栈-网络编程-TCP粘包
一.什么是TCP粘包 C/S架构下,接收方不知道每个消息的发送间隙.也不知道每次应该提取多少个字节的数据,与此同时,TCP是面向连接的,面向流的,收发两端都要有,因此发送端为了将多个发往接收端的数据包 ...
- socket编程解决粘包和丢包问题
##socket 丢包粘包解决方式 采用固定头部长度(一般为4个字节),包头保存的是包体的长度 header+body 包头+包体 下面的例子不是按照上图中规定的格式编写的,但是思路都是一样的,先读出 ...
- Socket编程 Tcp和粘包
大多数程序员都要接触网络编程,Web开发天天和http打交道.稍微底层一点的程序员,就是TCP/UDP . 对程序员来说,Tcp/udp的核心是Socket编程. 我的浅薄的观点---------理解 ...
- Socket编程(4)TCP粘包问题及解决方案
① TCP是个流协议,它存在粘包问题 TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的.这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的.T ...
- Socket编程实践(5) --TCP粘包问题与解决
TCP粘包问题 由于TCP协议是基于字节流且无边界的传输协议, 因此很有可能产生粘包问题, 问题描述如下 对于Host A 发送的M1与M2两个各10K的数据块, Host B 接收数据的方式不确定, ...
- 查漏补缺:socket编程:TCP粘包问题和常用解决方案(上)
1.TCP粘包问题的产生(发送端) 由于TCP协议是基于字节流并且无边界的传输协议,因此很容易产生粘包问题.TCP的粘包可能发生在发送端,也可能发生在接收端.发送端的粘包是TCP协议本身引起的,TCP ...
随机推荐
- 基于名称的虚拟主机-Apache
基于名称的虚拟主机和基于IP的虚拟主机的对比 基于IP的虚拟主机使用连接的IP地址来识别(区分)正确的虚拟主机,所以对于每一个虚拟主机,你都需要有独立的IP地址. 基于名称的虚拟主机,服务器依赖于客户 ...
- dedecms会员中心编辑器无法上传图片
文件:include\dialog\config.php 找到这行代码: $cuserLogin = new userLogin(); 把上面代码下面的这些注释掉: if($cuserLogin-&g ...
- xcode在代码中查找中文
总是忘记xcode中查找中文,这次记下来,以后就不会忘记了,哈哈 请看下图: 切换到查找,点击find后面的text,选择Regular Expression,然后输入 1. 查找非ascii的字符 ...
- 读Linear Algebra -- Gilbert Strang
转眼间我的学士学位修读生涯已经快要到期了,重读线性代数,一是为了重新理解Algebra的的重要概念以祭奠大一刷过的计算题,二是为了将来的学术工作先打下一点点(薄弱的)基础.数学毫无疑问是指导着的科研方 ...
- Memcache笔记02-telnet操作memcached
telnet操作Memcached 登录到telnet连接到memcached服务: telnet 127.0.0.1 11211 memcached的基本命令: //当telnet登录成功可以看到一 ...
- hdfs校验和
hdfs完整性:用户希望储存和处理数据的时候,不会有任何损失或者损坏.所以提供了两种校验: 1.校验和(常用循环冗余校验CRC-32). 2.运行后台进程来检测数据块. 校验和: a.写入数据节点验证 ...
- WAMP安装提示缺少 msvcr100.dll文件解决方法
WAMP安装提示缺少wamp msvcr100.dll文件解决方法 因为wamp基于vs c++2010开发,需要提前安装这个组件才可以正常运行 微软官方组件下载地址: 32位:http://www. ...
- 【UML】协作图Collaboration diagram(交互图)(转)
http://blog.csdn.net/sds15732622190/article/details/49402269 前言 学完UML时序图,就要看一下UML协作图,因为两张图是相 ...
- [神经网络]一步一步使用Mobile-Net完成视觉识别(一)
1.环境配置 2.数据集获取 3.训练集获取 4.训练 5.调用测试训练结果 6.代码讲解 本文是第一篇,环境配置篇. 先打开tensorflow object detection api 看看需要什 ...
- SQLServer死锁
死锁的四个必要条件:互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用.请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源.非剥夺条件( ...