socket 通信
服务端
- import socket
- server = socket.socket() # 买手机 不传参数默认用的就是 TCP 协议
- server.bind(('127.0.0.1',8080)) # bind((host,port)) 插电话卡 绑定 ip 和端口
- server.listen(5) # 开机 半连接池
- conn, addr = server.accept() # 接听电话 等着别人给你打电话 阻塞
- data = conn.recv(1024) # 听别人说话 接收 1024 个字节数据 阻塞
- print(data)
- conn.send(b'hello baby~') # 给别人回话
- conn.close() # 挂电话
- server.close() # 关机
客户端
- import socket
- client = socket.socket() # 拿电话
- client.connect(('127.0.0.1',8080)) # 拨号 写的是对方的 ip 和 port
- client.send(b'hello world!') # 对别人说话
- data = client.recv(1024) # 听别人说话
- print(data)
- client.close() # 挂电话
连接循环 + 通信循环
服务端
- import socket
- """
- 服务端
- 固定的 ip 和 port
- 24 小时不间断提供服务
- """
- server = socket.socket() # 生成一个对象
- server.bind(('127.0.0.1',8080)) # 绑定 ip 和 port
- server.listen(5) # 半连接池
- while True:
- conn, addr = server.accept() # 等到别人来 conn 就类似于是双向通道
- print(addr) # ('127.0.0.1', 51323) 客户端的地址
- while True:
- try:
- data = conn.recv(1024)
- print(data) # b''针对 Mac 与 Linux 客户端异常退出之后 服务端不会报错 只会一直收 b''
- if len(data) == 0:break
- conn.send(data.upper())
- except ConnectionResetError as e:
- print(e)
- break
- conn.close()
客户端
- import socket
- 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)
- data = client.recv(1024)
- print(data)
TCP 黏包问题
服务端
- import socket
- server = socket.socket() # 买手机 不传参数默认用的就是 TCP 协议
- server.bind(('127.0.0.1',8080)) # bind((host,port)) 插电话卡 绑定 ip 和端口
- server.listen(5) # 开机 半连接池
- conn, addr = server.accept() # 接听电话 等着别人给你打电话 阻塞
- data = conn.recv(5) # 听别人说话 接收 1024 个字节数据 阻塞
- print(data)
- data = conn.recv(5) # 听别人说话 接收 1024 个字节数据 阻塞
- print(data)
- data = conn.recv(4) # 听别人说话 接收 1024 个字节数据 阻塞
- print(data)
客户端
- import socket
- client = socket.socket() # 拿电话
- client.connect(('127.0.0.1',8080)) # 拨号 写的是对方的 ip 和 port
- client.send(b'hello')
- client.send(b'world')
- client.send(b'baby')
解决黏包问题
服务端
- 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.stdout.read() + obj.stderr.read()
- d = {'name':'jason','file_size':len(res),'info':'asdhjkshasdad'}
- 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)
- # conn.send(obj.stdout.read())
- # conn.send(obj.stderr.read())
- except ConnectionResetError:
- break
- conn.close()
客户端
- import socket
- 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'): # real_size = 102400
- data = client.recv(1024)
- real_data += data
- recv_size += len(data)
- print(real_data.decode('gbk'))
来源: http://www.bubuko.com/infodetail-3152955.html