一、socket模块 socket模块提供了底层的接口,通过socket模块可以实现不同计算机的通信 ip+port定位了计算机中应用程序的具体位置,socket绑定ip+port来建立链接,socket的方法详情: socket(family, type, proto): socket函数创建一个socket对象,使用socket对象创建连接, family协议族,默认AF_INET,ipv4协议,type,socket类型,proto协议类型 bind((ip, port)): 绑定服务器地址 listen(n): 监听socket创建的链接, n代表指定连接队列数, connect(('127.0.0.1', 8080)): 连接到服务端 accept():等待客户端连接,返回连接对象和客户端ip组成的元组 recv(n): 接收数据,n代表接受固定的数据 send(data): 发送数据 例子:模拟客户端服务端通信 server: #!/usr/bin/python # --*-- coding: utf-8 --*-- import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.bind(('127.0.0.1', 8080)) phone.listen(5) print('starting...') conn, addr = phone.accept() print(conn) print('client addr: ', addr) print('ready to read msg') client_msg = conn.recv(1024) print('client msg: %s' %(client_msg)) conn.send(client_msg.upper()) conn.close() phone.close() client #!/usr/bin/pytthon # --*-- coding: utf-8 --*-- import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) phone.send('hello'.encode('utf-8')) back_msg = phone.recv(1024) print(back_msg.decode('gbk')) phone.close() 模拟循环发送接收数据 server import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.bind(('127.0.0.1', 8080)) phone.listen(5) while True: print('starting...') conn, addr = phone.accept() print('client addr ', addr) while True: try: client_msg = conn.recv(1024) if not client_msg: break print('client_msg: %s' %client_msg) conn.send(client_msg.upper()) except Exception: break conn.close() phone.close() client import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) while True: msg = input(">>: ") if not msg: continue phone.send(msg.encode('utf-8')) back_msg = phone.recv(1024) print(back_msg.decode('utf-8')) phone.close() 模拟远程执行命令,并返回结果 server import socket import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.bind(('127.0.0.1', 8080)) phone.listen(5) while True: print('starting...') conn,addr = phone.accept() print('client addr: ', addr) while True: try: cmd = conn.recv(1024) if not cmd: break res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() if err: cmd_res = err else: cmd_res = res.stdout.read() conn.send(cmd_res) except Exception: break conn.close() phone.close() client import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) while True: cmd = input('>>: ').strip() if not cmd: continue phone.send(cmd.encode('utf-8')) back_msg = phone.recv(1024) print(back_msg.decode('gbk')) phone.close() 粘包现象,数据包无规则断开,出现不希望的断开现象 server from socket import * import time tcp_server = socket(AF_INET, SOCK_STREAM) tcp_server.bind(('127.0.0.1', 8080)) tcp_server.listen(5) conn, addr = tcp_server.accept() res1 = conn.recv(5) res2 = conn.recv(5) res3 = conn.recv(7) print(res1.decode('gbk')) print(res2.decode('gbk')) print(res3.decode('gbk')) client from socket import * import time tcp_client = socket(AF_INET, SOCK_STREAM) tcp_client.connect(('127.0.0.1', 8080)) tcp_client.send('hello world'.encode('utf-8')) time.sleep(5) tcp_client.send('egon666'.encode('utf-8')) 解决粘包问题,使用struct模块,打包数据并解包数据 例子: server import socket import subprocess import struct import json phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(('127.0.0.1', 8080)) phone.listen(5) while True: print('starting...') conn, addr = phone.accept() print('client addr: ', addr) while True: try: cmd = conn.recv(1024) if not cmd:break res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() if err: cmd_res = err else: cmd_res = res.stdout.read() head_dict = {'filename': None, 'hash': None, 'total_size': len(cmd_res)} head_json = json.dumps(head_dict) head_bytes = head_json.encode('utf-8') print(struct.pack('i', len(head_bytes))) conn.send(struct.pack('i', len(head_bytes))) conn.send(head_bytes) conn.send(cmd_res) except Exception: break conn.close() phone.close() client import socket import struct import json phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8080)) while True: cmd = input('>>: ').strip() if not cmd: continue phone.send(cmd.encode('utf-8')) head_struct = phone.recv(4) #print(head_struct) head_len = struct.unpack('i', head_struct)[0] head_bytes = phone.recv(head_len) head_json = head_bytes.decode('utf-8') #print(head_json) head_dict = json.loads(head_json) #print(head_dict) total_size = head_dict['total_size'] recv_size = 0 data = b'' while recv_size < total_size: recv_data = phone.recv(1024) data += recv_data recv_size += len(recv_data) print(data.decode('gbk')) phone.close()