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等数据