引子
什么是网络:一堆网络设备和一堆协议组成
协议:计算机届的英语、互联网协议价物理链接介质
应用层
传输层:TCP/UDP,基于端口通信
网络层
数据链路层:规定数据报的概念,基于mac广播的方式(找到同一子网的地址), 所以要IP(IP+子网掩码找到网络地址),跑以太网协议,mac地址固定,ip地址可变
物理层:单纯的二进制数,
一串二进制数字称为数据帧/数据报
两部分:报头:描述数据部分 固定长度的报头 数据部分
socket:应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口
多道技术:多道程序
linux:一切皆文件
套接字: 基于网络通信的
套接字家族: 套接字的工作流程: 多网卡
套接字
基于文件类型的套接字家族
套接字家族名字:AF_UNIX
基于网络类型的套接字家族
套接字家族名字:AF_INET
服务端套接字函数
s.bind()绑定
s.listen() 开始TCP监听
s.accept()被动接受TCP客户的连接,等待连接的到来
客户端套接字函数
s.connect()主动初始化TCP服务器连接
s.connect_e()connect()函数的扩展版本,出错时返回错误码而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据
s.send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
s.sendall() 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
s.recvfrom() 接收UDP数据
s.sendto() 发送UDP数据
s.getpeername() 连接到当前套接字的远端的地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回指定套接字的参数
s.setsockopt() 设置指定套接字的参数
s.close() 关闭套接字
面向锁的套接字方法
s.setblocking() 设置套接字的阻塞与非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 得到阻塞套接字操作的超时时间
面向文件的套接字的函数
s.fileno() 套接字的文件描述符
s.makefile() 创建一个与该套接字相关的文件
模拟ssh远程执行命令
![]()
import socket
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080)) #绑定到端口上,IP地址是以元祖的形式绑上去的,127是本机地址,也叫回环地址
phone.listen(5) #开机
print('starting...')
while True: #链接循环
conn,client_addr=phone.accept() #等电话 (链接,客户的的ip和端口组成的元组)
print('-------->',conn,client_addr)
#收,发消息
while True:#通信循环
try:
cmd=conn.recv(1024)
if not cmd:break #针对linux
# 执行cmd命令,拿到cmd的结果(结果应该是bytes类型)
res = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=res.stdout.read()
stderr=res.stderr.read()
#发送命令结果
conn.send(stdout+stderr)
except Exception:
break
conn.close() #挂电话
phone.close() #关机
服务端