python 客户端与服务端传输问题

灵猫海特 2019-01-26 05:10:48
server端代码

import socket
import os
server=socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
conn,addr = server.accept()
print('new conn:',addr)
while True:
data=conn.recv(1024)
if not data:
print('客户端已断开')
break
print('执行指令',data)
cmd_res = os.popen(data.decode()).read()
print('before send',len(cmd_res))
if len(cmd_res)==0:
cmd_res='cmd has no output'
conn.send(str(len(cmd_res)).encode('utf-8'))#先发数据大小给客户端
conn.send(cmd_res.encode('utf-8'))
print('send done')
server.close()


client端代码

import socket
import os

client = socket.socket()
client.connect(('localhost',9999))
while True:
cmd=input('>>>:').strip()
if len(cmd) == 0: continue
client.send(cmd.encode('utf-8'))
cmd_res_size=client.recv(1025) #接受命令结果的长度
print('命令结果大小:',cmd_res_size.decode())
receive_size = 0
while receive_size < int(cmd_res_size.decode()):
data = client.recv(1024)
receive_size += len(data)
#print(data.decode())
print(receive_size)
else:
print('cmd res receive done', receive_size)
#print(cmd_res.decode('utf-8'))
client.close()

执行后clien结果
"C:\Program Files\python37\python.exe" C:/Users/chan/Documents/我的坚果云/basic/real/day7/sock_server_client.py
>>>:dir
命令结果大小: 357
431
cmd res receive done 431
>>>:ipconfig/all
命令结果大小: 2187
1024
2048
2721
cmd res receive done 2721
>>>:dir
命令结果大小: 357
431
cmd res receive done 431
>>>:ipconfig
命令结果大小: 781
1024
cmd res receive done 1024
>>>:dir
Traceback (most recent call last):
命令结果大小: . . . . . . :
File "C:/Users/chan/Documents/我的坚果云/basic/real/day7/sock_server_client.py", line 13, in <module>

while receive_size < int(cmd_res_size.decode()):
ValueError: invalid literal for int() with base 10: '. . . . . . : \n'

Process finished with exit code 1

server端结果
"C:\Program Files\python37\python.exe" C:/Users/chan/Documents/我的坚果云/basic/real/day7/sock_server_ssh.py
new conn: ('127.0.0.1', 4459)
执行指令 b'dir'
before send 357
send done
执行指令 b'ipconfig/all'
before send 2187
send done
执行指令 b'dir'
before send 357
send done
执行指令 b'ipconfig'
before send 781
send done
执行指令 b'dir'
Traceback (most recent call last):
before send 357
File "C:/Users/chan/Documents/我的坚果云/basic/real/day7/sock_server_ssh.py", line 20, in <module>
conn.send(cmd_res.encode('utf-8'))
ConnectionAbortedError: [WinError 10053] 你的主机中的软件中止了一个已建立的连接。

由于是初学,找了半天没有发现原因,请大神解答一下,感觉就是干好等于1024的时候才会出错,试过别的命令都不会。谢谢
...全文
303 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
灵猫海特 2019-01-26
  • 打赏
  • 举报
回复
终于找到原因了,由于字符编码的问题导致。
server端返回的的大小,小于1024,而client端接收到的大小刚好等于1024.导致循环出错。
conn.send(str(len(cmd_res)).encode('utf-8'))#先发数据大小给客户端
conn.send(str(len(cmd_res.encode())).encode('utf-8'))#先发数据大小给客户端

这样收发大小就一样了


灵猫海特 2019-01-26
  • 打赏
  • 举报
回复
引用 1 楼 ruancan 的回复:
看报错信息是说返回的数据长度无法转换成int类型导致的,会不会是你开启了多个client,并发的时候导致的?一般我们制定socket的协议时会在头四位上制定数据长度,而不是长度和内容分开传输


运行ipconfig命令后,再运行其他命令会报错。但是运行其他的命令都不会,不管是重复命令还是改变命令。
ruancan 2019-01-26
  • 打赏
  • 举报
回复
看报错信息是说返回的数据长度无法转换成int类型导致的,会不会是你开启了多个client,并发的时候导致的?一般我们制定socket的协议时会在头四位上制定数据长度,而不是长度和内容分开传输

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧