前言
在远程执行命令博客示例中,示例并不完美,但是就代码而言,没有最好的代码,只有更好的代码。但是在该示例中,有一个BUG可想而知,就是在客户端的sk.revc()函数中,只指定了接收1024个字节,那如果服务端发送的数据超过了1024个字节呢?此时数据会接收不完整,为了解决此问题,我们需要引入一些新的东西。
基本思路
- 先让服务端计算一下要发送数据的大小
- 将此大小的这个数值(int)发送给客户端,让客户端知道你需要接收多大的数据
- 客户端根据这个大小来判断需要循环几次来接收服务端一次性发送的数据。
示例代码
服务器端代码
import socket
import subprocess
sk = socket.socket()
address = ("127.0.0.1",9200)
sk.bind(address)
sk.listen(3)
print("waiting.....")
connection,clientinfo = sk.accept()
print(connection)
print(clientinfo)
while True:
try:
print("waiting for message input.....")
user_recv = connection.recv(1024)
except ConnectionResetError as e:
connection.close()
print(e)
print(clientinfo,"已经主动关闭了会话")
connection, clientinfo = sk.accept()#因为上面对connection关闭了,所以这里需要重新来一个connection等待连接
continue
if not user_recv:# 当用户输入exit的时候,服务端会接收到一个“空”的内容,所以判断用户终止了会话,所以我们接收一个新的连接。
print("当前用户已经退出会话。")
connection.close()
connection, clientinfo = sk.accept()
print("新用户建立了一个连接,客户端信息:",clientinfo)
continue
command = str(user_recv,"utf8")
command_result = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
command_result_str = command_result.stdout.read()
#计算出数据有多大
result_length = len(command_result_str)
print("发送数据大小为:",result_length)
try:
connection.sendall(bytes(str(result_length),"gbk"))
connection.sendall(command_result_str)
print("运行结果已经发送")
except ConnectionResetError as e:
connection.close()
print(e)
print(clientinfo,"已经主动关闭了会话")
connection, clientinfo = sk.accept()#因为上面对connection关闭了,所以这里需要重新来一个connection等待连接
continue
connection.close()
客户端代码
import socket
sk = socket.socket()
address = ("127.0.0.1",9200)
sk.connect(address)
while True:
user_input = input(">>>")
if user_input == "exit":
print("exiting....")
break
if not user_input:
print("输入数据不允许为空,请重新输入.")
continue
sk.send(bytes(user_input,"utf8"))
#先接收服务端发送过来的数据长度数值
result_recv = int(str(sk.recv(1024),"utf8"))
print(str(result_recv))
# 新建一个bytes类型的空数据,用于存储即将接收到的bytes的数据。而且每循环一次都要往后面累加数据
data = bytes()
while len(data) != result_recv:
user_recv = sk.recv(1024)
print("接收到%s数据。"%(len(user_recv)))
data += user_recv
else:
print("总共接收到%s数据。"%(len(data)))
print("接收数据完成")
print(str(data,"gbk"))
sk.close()
运行结果展示
>>>ipconfig
1615
接收到1024数据。
接收到591数据。
总共接收到1615数据。
接收数据完成
Windows IP Configuration
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . : xxxxx.com.cn
Link-local IPv6 Address . . . . . : fe80::2c4b:39e4:88c1:49dd%13
Link-local IPv6 Address . . . . . : fe80::51b0:72cf:65:ad49%13
IPv4 Address. . . . . . . . . . . : 192.168.255.52
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : ::
Ethernet adapter 以太网:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::e5db:5993:684:a0c4%10
IPv4 Address. . . . . . . . . . . : 192.168.1.3
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
Ethernet adapter loopback0:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::d9ba:7cc6:cae6:c7aa%14
IPv4 Address. . . . . . . . . . . : 192.168.100.254
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
Ethernet adapter VMware Network Adapter VMnet1:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::991:4897:10f8:18f3%8
IPv4 Address. . . . . . . . . . . : 192.168.169.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
Ethernet adapter VMware Network Adapter VMnet8:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::e9db:995e:e588:67ca%6
IPv4 Address. . . . . . . . . . . : 192.168.128.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
>>>ipconfig /all
5478
接收到1024数据。
接收到1024数据。
接收到1024数据。
接收到1024数据。
接收到1024数据。
接收到358数据。
总共接收到5478数据。
接收数据完成
Windows IP Configuration
Host Name . . . . . . . . . . . . : DESKTOP-JT18FSK
Primary Dns Suffix . . . . . . . :
Node Type . . . . . . . . . . . . : Hybrid
IP Routing Enabled. . . . . . . . : No
WINS Proxy Enabled. . . . . . . . : No
DNS Suffix Search List. . . . . . : cjfco.com.cn
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . : xxxx.com.cn
Description . . . . . . . . . . . : Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windows x64
Physical Address. . . . . . . . . : 00-05-9A-3C-7A-00
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::2c4b:39e4:88c1:49dd%13(Preferred)
Link-local IPv6 Address . . . . . : fe80::51b0:72cf:65:ad49%13(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.255.52(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : ::
DHCPv6 IAID . . . . . . . . . . . : 218105242
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-24-E9-11-5A-00-E0-1B-68-01-75
DNS Servers . . . . . . . . . . . : 10.243.1.1
10.243.1.2
NetBIOS over Tcpip. . . . . . . . : Enabled
Ethernet adapter 以太网:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Realtek PCIe GbE Family Controller
Physical Address. . . . . . . . . : 00-E0-1B-68-01-75
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::e5db:5993:684:a0c4%10(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.1.3(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Lease Obtained. . . . . . . . . . : 2020年10月1日 17:17:17
Lease Expires . . . . . . . . . . : 2020年10月2日 17:17:06
Default Gateway . . . . . . . . . : 192.168.1.1
DHCP Server . . . . . . . . . . . : 192.168.1.1
DHCPv6 IAID . . . . . . . . . . . : 100720667
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-24-E9-11-5A-00-E0-1B-68-01-75
DNS Servers . . . . . . . . . . . : fe80::1%10
192.168.1.1
fe80::1%10
NetBIOS over Tcpip. . . . . . . . : Enabled
Ethernet adapter loopback0:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Microsoft KM-TEST Loopback Adapter
Physical Address. . . . . . . . . : 02-00-4C-4F-4F-50
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::d9ba:7cc6:cae6:c7aa%14(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.100.254(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
DHCPv6 IAID . . . . . . . . . . . : 503447628
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-24-E9-11-5A-00-E0-1B-68-01-75
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
NetBIOS over Tcpip. . . . . . . . : Enabled
Ethernet adapter VMware Network Adapter VMnet1:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : VMware Virtual Ethernet Adapter for VMnet1
Physical Address. . . . . . . . . : 00-50-56-C0-00-01
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::991:4897:10f8:18f3%8(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.169.1(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Lease Obtained. . . . . . . . . . : 2020年10月1日 17:17:09
Lease Expires . . . . . . . . . . : 2020年10月1日 19:32:02
Default Gateway . . . . . . . . . :
DHCP Server . . . . . . . . . . . : 192.168.169.254
DHCPv6 IAID . . . . . . . . . . . : 234901590
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-24-E9-11-5A-00-E0-1B-68-01-75
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
NetBIOS over Tcpip. . . . . . . . : Enabled
Ethernet adapter VMware Network Adapter VMnet8:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : VMware Virtual Ethernet Adapter for VMnet8
Physical Address. . . . . . . . . : 00-50-56-C0-00-08
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::e9db:995e:e588:67ca%6(Preferred)
IPv4 Address. . . . . . . . . . . : 192.168.128.1(Preferred)
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Lease Obtained. . . . . . . . . . : 2020年10月1日 17:17:09
Lease Expires . . . . . . . . . . : 2020年10月1日 19:32:02
Default Gateway . . . . . . . . . :
DHCP Server . . . . . . . . . . . : 192.168.128.254
DHCPv6 IAID . . . . . . . . . . . : 251678806
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-24-E9-11-5A-00-E0-1B-68-01-75
DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
Primary WINS Server . . . . . . . : 192.168.128.2
NetBIOS over Tcpip. . . . . . . . : Enabled
>>>