网络编程ssh,粘包

Posted zhangqing979797

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程ssh,粘包相关的知识,希望对你有一定的参考价值。

1.什么是socket?

TCP,可靠地,面向连接协议,有阻塞rect 

udp,不可靠的,无线连接的服务 这里因为不需要阻塞,所以速度会很快,但安全性不高

2.关于客户端退出而服务器未退出的解决办法

 1 import socket
 2 sock=socket.socket() # TCP协议
 3 IP_PORT=("127.0.0.1",8899)
 4 sock.bind(IP_PORT)
 5 sock.listen(5)
 6 while 1:
 7     conn,addr=sock.accept()
 8     while 1:
 9         try:#这里是因为如果当客户端完成登陆后,由于客户端的退出,而
10             #服务端只是刚刚退出第一层循环,还在等着接收客户端传来的信息,所以
11             #会报错 只需要加一个异常处理,如果客户端离开则不会等待客户传来信息
12             #会处于待命状态,等待下一次传入
13             data=conn.recv(1024).decode("utf8")
14             print("接收信息:",data)
15             print("接收信息:",type(data))
16             print("-----",data.split("|"))
17             user,pwd=data.strip().split("|")
18             # 文件操作
19             flag=False
20             with open("account","r") as f:
21 
22                 for line in f:
23                     print("===",line.strip().split(":"))
24                     username,password=line.strip().split(":")
25                     if username==user and password==pwd:
26                         flag=True
27                         break
28             if flag:
29                 conn.send(b"success")
30             else:
31                 conn.send(b"fail")
32         except Exception as e:
33             break

客户端

 1 import socket
 2 
 3 sock=socket.socket() # TCP
 4 sock.connect(("127.0.0.1",8899))
 5 
 6 while 1:
 7     user=input("用户名>>>>")
 8     pwd=input("密码>>>>")
 9     val=("%s|%s"%(user,pwd)).encode("utf8")
10     sock.send(val)
11     response=sock.recv(1024)
12     print(response.decode("utf8"))
13     if response.decode("utf8")=="success":
14         break
15     else:
16         print("用户名或者密码错误!")
17         continue

3.模拟ssh

 1 import struct
 2 
 3 #打包
 4 res=struct.pack("i","")#这里可以放数字
 5 
 6 print(res)#最终显示的是4个字节
 7 print(len(res))#始终四个字节.长度为4
 8 
 9 obj=struct.unpack("i",res)#用于解包,最后显示元祖,后面一逗号结尾
10 print(obj[0])#获取解包后的数字
11 #struct模块主要用于当发生粘包时.由于向客户端/服务端发送两个
12 #字节时,计算机无法判断前后位置,所以又来区分因为打包后固定长度为4
13 #所以取前四段
14 bxxx/xxx/xxx/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
15 #就可以区分了
16 #当然也可以用时间(睡眠)来区分

 

1 import subprocess#可以使cmd之间的程序在python中显示
2 
3 res=subprocess.Popen("dir",#进行命令
4                      shell=True,
5                      stderr=subprocess.PIPE,#终端错误输出stderr
6                      stdout=subprocess.PIPE)# 终端输出stdout
7 
8 print(res.stdout.read().decode("gbk"))##返回的字节所以用gbk
9 #可以实现将cmd中的命令显示在python
 1 import socket
 2 import subprocess
 3 server = socket.socket()
 4 server.bind((127.0.0.1,8008))
 5 server.listen(5)
 6 while True:
 7     print("server is working.....")
 8     conn,addr = server.accept()
 9     # 字节类型
10     while True:
11         # 针对window系统
12         try:
13             cmd = conn.recv(1024).decode("utf8") # 阻塞#客户端传入的命令需要解码显示成字符串的形式
14 
15             if cmd == bexit:
16                 break
17             # res=subprocess.Popen(cmd,#subprocess模块
18             #                  shell=True,
19             #                  stderr=subprocess.PIPE,
20             #                  stdout=subprocess.PIPE,
21             #                  )
22             # print("stdout",res.stdout.read())
23             # print("stderr",res.stderr.read().decode("gbk"))
24             out=res.stdout.read()#终端输出 显示的是使用命令的正确
25             err=res.stderr.read()#终端错误 显示的是不是系统命令的报错提示
26 
27             print("out响应长度",len(out))#知道长度才可以使他们逐一实现
28             print("err响应长度",len(err))
29             if err:
30                  import struct
31                  header_pack = struct.pack("i", len(err))#首先一定要给出长度,客户端才会跟据长度
32                  #来显示
33                  conn.send(header_pack)
34                  conn.send(err)
35             else:#没阻塞一次就发过去了
36                  #构建报头
37                  import struct#构建
38                  header_pack=struct.pack("i",len(out))#数字的长度压缩完成报头
39                  print("header_pack",header_pack)
40                  # # 发送报头#将报文连在一起发送
41                  conn.send(str(len(out)).encode("utf8"))#把数字转换成字符串,再转化成字节才可以发过去
42                  # 发送数据
43                  conn.send(out)#整体的数据
44 
45         except Exception as e:
46             break
47     conn.close()

客户端

 1 sk.connect((127.0.0.1,8008))
 2 
 3 while 1:
 4     cmd = input("请输入命令:")
 5     sk.send(cmd.encode(utf-8)) # 字节
 6     if cmd=="":
 7         continue
 8     if cmd == exit:
 9         break
10 
11     header_pack=sk.recv(4)#取前四个字节
12     data_length=struct.unpack("i",header_pack)[0]#解包
13     print("data_length",data_length)
14     ‘‘‘
15     b‘xxx/xxx/xxx/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb‘
16     
17     
18     ‘‘‘
19     data_length=int(sk.recv(1024).de- code("utf8"))
20     print("data_length",data_length)
21     recv_data_length=0#判断是否小于接收到的字节
22     recv_data=b""
23     while recv_data_length<data_length:
24         data=sk.recv(1024)
25         recv_data_length+=len(data)#接收多少就是这个
26         #实现的前提需要总长度,
27         recv_data+=data
28     print(recv_data.decode("gbk"))
29 sk.close()

3.关于粘包


粘包:发送长度和数据但是计算机不知道怎么去区分 两个send计算机不知道怎么区分
我们丢的东西没有丢
1.间隔短 2.文件不大3.
sleep 不让粘包

关于加密

 1 import hashlib
 2 
 3 # md5=hashlib.md5()
 4 # md5.update(b"hello")#当分别输入hello 和 yaun时 结果与helloyuan
 5 #一样,但是这样的好处是可以分开存储节省内存,要是一次写入那么多
 6 #会疯的
 7 # md5.update(b"yuan")
 8 #
 9 # print(md5.hexdigest())
10 # print(len(md5.hexdigest()))
11 
12 #helloyuan:   d843cc930aa76f7799bba1780f578439
13 #             d843cc930aa76f7799bba1780f578439
14 
15 #############################################
16 md5=hashlib.md5()
17 
18 with open("ssh_client.py","rb") as f:
19     for line in f:
20         md5.update(line)
21 
22 print(md5.hexdigest()) # f.read() 16位字节

 





以上是关于网络编程ssh,粘包的主要内容,如果未能解决你的问题,请参考以下文章

ssh 粘包

Python--网络编程-----粘包现象

socket网络编程:粘包现象以及解决方法(代码完善)

TCP网络通讯如何解决分包粘包问题(有模拟代码)

网络编程基础之粘包现象

3进程的基础理论,并发