zoukankan      html  css  js  c++  java
  • socket编程模拟linux下的ssh代码实现

    实现思路:

    1.提供输入指令的客户端;

    2.提供返回执行指令结果的服务端

    3.寻找服务端返回结果一次无法全部接收的解决思路

    服务端代码(ssh_server.py)

     1 #coding=utf-8
     2 import socket,os
     3 
     4 server = socket.socket()
     5 server.bind(('localhost', 9999))
     6 server.listen()
     7 client,addr = server.accept()
     8 while True:
     9     data = client.recv(1024)
    10     if data == '' or data == None:continue
    11     cmd_res = os.popen(data.decode()).read()
    12     if len(cmd_res) == 0:
    13         cmd_res = '指令无效,请重新输入'
    14     client.send(str(len(cmd_res.encode('utf-8'))).encode('utf-8'))
    15     client.recv(1024)#更改后
    16     client.send(cmd_res.encode('utf-8'))
    17     print(len(cmd_res))
    18 server.close()

    客户端代码(ssh_client.py)
     1 # coding = utf-8
     2 import socket
     3 
     4 client = socket.socket()
     5 client.connect(('localhost',9999))
     6 while True:
     7     cmd = input('>>:').strip()
     8     if len(cmd) == 0:continue
     9     client.send(cmd.encode('utf-8'))
    10     data_size = int(client.recv(1024).decode())
    11     print(data_size)    #字节大小
    12     curr_size = 0
    13     final_res = b''
    14     while data_size != curr_size:
    15         data = client.recv(1024)
    16         curr_size += len(data)
    17         print(curr_size)
    18         final_res+=data
    19     print(final_res.decode())

    潜在问题
    由于服务器两次发送的数据间歇时间太短,容易造成粘包(服务器发送出的两条信息同时到缓存中,缓存区未满或未超时时内部机制是知道缓存区满才将消息拿出来,多次发送的信息资料由于此种机制的制约
    很容易造成粘包,解决思路a.服务器两次发送信息中间加一个是时间间隙,time.sleep(2);b.服务端发出上一条信息后客户端接受到消息后向服务器返回一个标识,服务端接受到该标识后再发送第二波消息)
    改进后代码(ssh_server.py):
    
    
    #coding=utf-8
    import socket,os

    server = socket.socket()
    server.bind(('localhost', 9999))
    server.listen()
    client,addr = server.accept()
    while True:
    data = client.recv(1024)
    if data == '' or data == None:continue
    cmd_res = os.popen(data.decode()).read()
    if len(cmd_res) == 0:
    cmd_res = '指令无效,请重新输入'
    client.send(str(len(cmd_res.encode('utf-8'))).encode('utf-8'))
    client.recv(1024)#b方式更改后
    client.send(cmd_res.encode('utf-8'))
    print(len(cmd_res))
    server.close()

    改进后代码(ssh_client.py

    
    
    # coding = utf-8
    import socket

    client = socket.socket()
    client.connect(('localhost',9999))
    while True:
    cmd = input('>>:').strip()
    if len(cmd) == 0:continue
    client.send(cmd.encode('utf-8'))
    data_size = int(client.recv(1024).decode())
    client.send("received the message...")#b方式更改后
    print(data_size) #字节大小
    curr_size = 0
    final_res = b''
    while data_size != curr_size:
    data = client.recv(1024)
    curr_size += len(data)
    print(curr_size)
    final_res+=data
    print(final_res.decode())
     
    
    
  • 相关阅读:
    错误1053:服务没有及时响应启动或控制请求
    错误号码2003 Can't connect to MySQL server 'localhost' (0)
    分析slow-log 每小时慢sql情况
    用spring annotation声明的bean,当打包在jar中时,无法被扫描到
    mysql 锁查看
    linux 使用expect
    tomcat启动报错:java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener
    Spring LDAP authenticate method with Pooling
    一步步教你使用Proguard混淆Java源代码
    JAVA获取CLASSPATH路径
  • 原文地址:https://www.cnblogs.com/g177w/p/8119968.html
Copyright © 2011-2022 走看看