socket

  1. """服务器端函数"""
  2. s.bind() # 绑定(主机ip,端口号)
  3. s.listen() # 开始TCP监听
  4. s.accpet() # 被动接受TCP客户端的连接
  5. """客户端函数"""
  6. s.connect() # 主动初始化TCP服务器连接
  7. s.connect_ex() # connect函数的扩展版本,出错时返回出错码,而不抛出异常
  8. """公共用途函数"""
  9. s.recv() # 接收TCP数据
  10. s.send() # 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完)
  11. s.sendall() # 发送完整的TCP数据(本质就是循环调用send,sendall在待发送数据量大于己端缓存区剩余空间时,数据不丢失,循环调用send直到发完)
  12. s.recvfrom() # 接收UDP数据
  13. s.sendto() # 发送UDP数据
  14. s.getpeername() # 连接到当前套接字的远端的地址
  15. s.getsockname() # 当前套接字的地址
  16. s.getsockopt() # 返回指定套接字的参数
  17. s.setsockopt() # 设置指定套接字的参数
  18. s.close() # 关闭套接字
  19. """锁"""
  20. s.setblocking() # 设置提交者的阻塞与非阻塞模式
  21. s.settimeout() # 设置阻塞套接字操作的超时时间
  22. s.gettimeout() # 得到阻塞套接字操作的超时时间
  23. """文件套接字函数"""
  24. s.fileno() # 套接字的文件描述符
  25. s.makefile() # 创建一个与该套接字相关的文件

TCP

服务端

  1. import socket
  2. """
  3. AF_UNIX 文件
  4. AF_INET ipv4
  5. AF_INET6 ipv6
  6. SOCK_STREAM tcp模式
  7. SOCK_DGRAM udp模式
  8. """
  9. # 创建socket
  10. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  11. # 配置socket,重用ip和端口
  12. server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  13. # 绑定ip地址
  14. server.bind(('127.0.0.1', 8080))
  15. # 监听连接
  16. server.listen(5)
  17. while True:
  18. # 等待客户端连接
  19. conn, addr = server.accept()
  20. while True:
  21. try: # 针对windows 客户端端口连接处理
  22. # 接收客户端数据
  23. data = conn.recv(1024)
  24. if not data: # 针对linux 客户端断开连接处理
  25. break
  26. # 发送数据给客户端
  27. conn.send('111')
  28. except ConnectionResetError:
  29. print('客户端断开连接')
  30. break
  31. # 关闭客户端连接
  32. conn.close()
  33. # 关闭服务端连接
  34. server.close()

客户端

  1. import socket
  2. # 创建scoket
  3. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  4. # 连接服务端
  5. client.connect(('127.0.0.1', 8080))
  6. while True:
  7. cmd = input('>>>').strip()
  8. if not cmd:
  9. continue
  10. client.send(cmd.encode('utf-8'))
  11. res = client.recv(1024)
  12. print(res.decode('utf-8'))
  13. client.close()

粘包

解决方法:发送数据报头

  1. """服务端"""
  2. 1. 定义报头字典
  3. 2. 将报头json.dumps()序列化,encode()转换成字节
  4. 3. 得到报头长度
  5. 4. 将报头长度打包,struct.pack(),'i' 固定长度4bytes
  6. 5. 发送报头长度
  7. 6. 发送报头
  8. 7. 发送数据
  9. """客户端"""
  10. 1. 接收报头长度,4个字节
  11. 2. 解包报头长度struct.unpack(),等到报头长度
  12. 3. 根据报头长度,接收报头
  13. 4. 将报头decode()转换成字符串,并json.loads()反序列化
  14. 5. 根据报头中数据长度,接收数据

struct

  1. import struct
  2. # 将数据打包
  3. struct.pack()
  4. # 将数据解包
  5. struct.unpack()

socketserver

  • 连接相关类
    • BaseServer
    • TCPServer
    • UDPServer
    • UnixStreamServer
    • UnixDatagramServer
  • 多线程相关类
    • ThreadingMixIn
    • ThreadingTCPServer
    • ThreadingUDPServer
  • 多进程相关类
    • ForkingMixIn
    • ForkingTCPServer
    • ForkingUDPServer
  • 通信相关类:
    • BaseRequestHandler
    • StreamRequestHandler
    • DataGramRequestHandler
  1. import socketserver
  2. class MyServer(socketserver.BaseRequestHandler):
  3. def handle(self):
  4. # self.request # 客户端连接socket对象
  5. pass
  6. if __name__ == '__main__':
  7. obj = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), MyServer)
  8. obj.serve_forever()

UDP

subprocess

  1. import subprocess
  2. # 执行命令
  3. res = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  4. # 获取命令执行结果
  5. res.stdout.read()
  6. # 如果不为空则命令执行错误,错误信息
  7. res.stderr.read()