基于TCP协议的Socket套接字
server端
import socket sk = socket.socket() sk.bind(('127.0.0.1',8898)) # 把地址绑定到套接字 sk.listen() # 监听链接 conn,addr = sk.accept() # 接受客户端链接 ret = conn.recv(1024) # 接收客户端信息 print(ret) # 打印客户端信息 conn.send(b'hi') # 向客户端发送信息 conn.close() # 关闭客户端套接字 sk.close() # 关闭服务器套接字(可选)
client端
import socket sk = socket.socket() # 创建客户套接字 sk.connect(('127.0.0.1',8898)) # 尝试连接服务器 sk.send(b'hello!') ret = sk.recv(1024) # 对话(发送/接收) print(ret) sk.close() # 关闭客户套接字
127.0.0.1本机回还地址:只能自己识别自己 其他人无法访问
send与recv对应,不要出现两边都是相同的情况
recv是跟内存要数据,至于数据的来源 你无需考虑
TCP特点
会将数据量比较小的并且时间间隔比较短的数据一次性打包发送给对方
TCP是基于链接的,必须先启动服务端,然后再启动客户端去连接服务端
解决粘包问题
服务端
1.先制作一个发送给客户端的字典
2.制作字典的报头
3.发送字典的报头
4.发送字典
5.再发真实数据
客户端
1.先接受字典的报头
2.解析拿到字典的数据长度
3.接受字典
4.从字典中获取真实数据的长度
5.接受真实数据
服务端代码
import socket import subprocess import struct import json server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) while True : conn,addr = server.accept() while True: try: cmd = conn.recv(1024) if len(cmd) == 0:break cmd = cmd.decode('utf-8') obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) res = obj.studout.read() + obj.stderr.read() d = {'name':'jason','file_size':len(res),'info':'aaaaaaazzzzzzz'} json_d = json.dumps(d) # 1.先制作一个字典的报头 header = struct.pack('i',len(json_d)) # 2.发送字典报头 conn.send(header) # 3.发送字典 conn.send(json_d.encode('utf-8)) # 4.再发送真实数据 conn.send(res) except ConnectionResetError: breakconn.close()
客户端代码
improt cocket import struct import json client = socket.socket client.connect(('127.0.0.1',8080)) while True: msg = input(>>>:).encode('utf-8') if len(msg) == 0:continue client.send(msg) # 1.先接收字典报头 header_dict = client.recv(4) # 2.解析报头 获取字典的长度 dict_size = struct.unpack('i',header_dict)[0] # 解包的时候一定要加上索引0 # 3.接收字典数据 dict_bytes = client.recv(dict_size) dict_json = json.loads(dict_bytes.decode('utf-8')) # 4.从字典中获取信息 print(dict_json) recv_size = 0 real_data = b'' while recv_size < dict_json.get('file_size'): data = client.recv(1024) real_data += data recv_size += len(data) print(real_data.decode('gbk'))
END