-
socket通信流程
-
粘包问题
由于sendall()在发送数据前要检查是否还有要发送的数据,虽然这个等待检查的过程很短,但是也有一定的几率造成原本要多次发送的数据,变成了一次全部发送。
#问题代码,可能会出现result_len+cmd_result合在一起被发送出去
conn.sendall(result_len)
conn.sendall(cmd_result)
通过在两个sendall()之间加一段conn.recv(1024)解决
#解决粘包
conn.sendall(result_len)
conn.recv(1024)
conn.sendall(cmd_result)
-
发送非交互cmd命令的代码实例
server端
import socket
import subprocess
ip_port = ('127.0.0.1', 8879)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
print("服务端启动...")
while True:
conn, address = sk.accept()
while True:
try:
#recv产生阻塞,等待client端send数据
client_data = conn.recv(1024)
except Exception:
break
print(str(client_data, "utf8"))
print("waiting...")
cmd = str(client_data, "utf8").strip()
cmd_call = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
cmd_result = cmd_call.stdout.read()
if len(cmd_result) == 0:
cmd_result = b"no output!"
conn.sendall(cmd_result)
print('send data size', len(cmd_result))
conn.close()
client端
import socket
ip_port = ('127.0.0.1', 8879)
sk = socket.socket()
sk.connect(ip_port)
print("客户端启动:")
while True:
inp = input('cdm:>>>').strip()
if len(inp) == 0:
continue
if inp == "q":
break
sk.sendall(bytes(inp, "utf8"))
#recv产生阻塞,等待server端send数据
server_response = sk.recv(1024)
print(str(server_response, "gbk"))
print('receive data size', len(server_response))
if inp == 'exit':
break
sk.close()