[Python 网络编程] TCP、简单socket模拟ssh (一)

OSI七层模型(Open System Interconnection,开放式系统互联)

应用层
    网络进程访问应用层:
        为应用程序进程(例如:电子邮件、文件传输和终端仿真)提供网络服务;
        提供用户身份验证

表示层
    数据表示:
        确保接收系统可以读出该数据;
        格式化数据;
        构建数据;
        协商用于应用层的数据传输语法;
        提供加密

回话层
    主机间通信:
        建立、管理和终止在应用程序之间的会话

传输层     
    传输问题:
        确保数据传输的可靠性;
        建立、维护和终止虚拟电路;
        通过错误检测和恢复;
        信息流控制来保证可靠性

网络层     
    数据传输:
        路由数据包;
        选择传递数据的最佳路径;
        支持逻辑寻址和路径选择


数据链路层  
    访问介质:
        定义如何格式化数据以便进行传输以及如何控制对网络的访问;
        支持错误检测


物理层     
    二进制传输:单位比特
        为启动、维护以及关闭物理链路定义了电器规范、机械规范、过程规范和功能 

  

socket    实例化一个套接字

bind      绑定到地址和端口

listen    开始监听

accept   等待wait传入连接

recv   接受数据

send   发送数据(默认发送大小是32768(32k)大小)

sendall 发送所有数据

close  关闭socket

  

 一、简单的通信过程

服务端:

import socket


#实例化,绑定,监听,等待,解构(标识,ip-port),接收,回应,关闭
server = socket.socket()

server.bind(('localhost',6969))
server.listen()
print('开始监听...')

conn,addr = server.accept()
print(conn,addr)

data = conn.recv(1024)
print('服务端接收到数据:',data.decode())

conn.send('Hi, i am the server.'.encode())

server.close()

  

客户端:

import socket


#实例化,连接,发送,接收回应,关闭
client = socket.socket()

client.connect(('localhost',6969))

client.send('Hi,i am the client.'.encode())
print('发送数据...')

data = client.recv(1024)
print('客户端接收到数据:',data.decode())

client.close()

 

输出结果: 

1. 先运行服务端,监听端口,开始等待传入数据:

开始监听...

2. 启动客户端,发送数据,接收响应:

发送数据...
客户端接收到数据: Hi, i am the server.

  

3. 回到服务端,查看接收到的数据:

开始监听...
<socket.socket fd=6, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 6969), raddr=('127.0.0.1', 55149)> ('127.0.0.1', 55149)
接收到的数据: Hi,i am the client.

  

二、模拟ssh远程命令执行

服务器端:

import socket
import time
import os

#实例化,绑定,监听,等待,解构(标识,ip-port),接收,响应,关闭
server = socket.socket()

server.bind(('localhost', 6969))
server.listen(3) #表示当正在处理一个连接时,最多可以按顺序挂起接下来的3个连接(可以理解成排队),如果第4个来连接,过了一定时间就会抛出超时异常:TimeoutError: [Errno 60] Operation timed out
print('开始监听...')

try:
    while True:
        conn,addr = server.accept()
        # print(conn,addr)
        peerip,peerport = conn.getpeername()
        localip,localport = conn.getsockname()
        print('{}:{} --> {}:{}'.format(peerip,peerport,localip,localport))

        while True:
            data = conn.recv(1024)
            if not data:
                break
            print(data.decode())
            ret = os.popen(data.decode()).read()
            conn.send(ret.encode())
    server.close()
except KeyboardInterrupt as e:
    print('连接被中断...')

  

  

客户端

import socket


#实例化,连接,发送,接收响应,关闭
client = socket.socket()

client.connect(('localhost',6969))
print('正在连接服务端...')

while True:
    msg = input('>>>').strip()
    # print('正在发送数据...')
    if not msg:
        continue
    client.send(msg.encode())
    # print('已发送...')

    data = client.recv(1024)
    if not data:
        break
    print(data.decode())

client.close()

  

  

运行结果:

1. 服务端:

开始监听...

2. 客户端(可以输入执行的命令,接收到服务端返回的执行结果):

正在连接服务端...
>>>ls -l
total 48
-rw-r--r--  1 zhangsan  staff   222 Nov 10 10:37 1.0.py
-rw-r--r--  1 zhangsan  staff   433 Nov 10 16:49 2.0.py
-rw-r--r--  1 zhangsan  staff   158 Nov 10 23:18 error.log
-rw-r--r--  1 zhangsan  staff   437 Nov 11 14:10 socket_client1.py
-rw-r--r--  1 zhangsan  staff  1010 Nov 11 14:21 socket_server1.py
-rw-r--r--  1 zhangsan  staff   608 Nov 10 23:31 异常处理.py

>>>ls -l ../
total 0
drwxr-xr-x   7 zhangsan  staff  224 Nov  8 12:51 1106
drwxr-xr-x  11 zhangsan  staff  352 Nov  9 11:33 1108
drwxr-xr-x   8 zhangsan  staff  256 Nov 11 14:21 1110

>>>

  

  

3. 服务端:  

开始监听...
127.0.0.1:56380 --> 127.0.0.1:6969
ls -l
ls -l ../    #记录执行的命令

  

 协议簇:

AF_INET   IPV4

AF_INET6  IPV6

AF_UNIX  本地地址

协议: Protocol

SOCK_STREAM  TCP

SOCK_DGRAM  UDP

SOCK_RAW    原始套接字,可伪造源IP等数据

原文地址:https://www.cnblogs.com/i-honey/p/7818657.html