服务器端:
流程:
1.创建servert实例
2.绑定地址和端口
3.开始监听
4.创建客户端连接实例
5.等待客户端的消息
6..........
1 # The_author = 'liu66' 2 # By python3.x 3 # -*- coding = utf-8 -*- 4 5 6 import socket,os 7 8 server=socket.socket() 9 server.bind(("localhost",66))#绑定要监听的端口 10 server.listen(5)#开始监听 11 # 等电话打进来 12 13 while True: 14 print("我要开始等电话了") 15 conn,addr=server.accept()#conn为连接的实例 16 print("实例的连接和地址分别为:",conn,addr) 17 while True: 18 print("等待数据接收...") 19 data=conn.recv(1024) 20 if not data: 21 print("client has closed...") 22 break 23 # print(data) 24 # print(data.decode()) 25 # conn.send(data.upper()) 26 # 执行cmd命令 27 try: 28 res = os.popen(data.decode()).read() 29 except TypeError: 30 print("请输入正确的CMD") 31 else: 32 print("------------------") 33 print(res)#打印返回的值 34 print("------------------") 35 '''一定要判断返回的长度''' 36 print(len(res)) 37 received_size='' 38 if len(res) == 0: 39 res = "cmd is not correct..." 40 print(res) 41 conn.send(str(len(res.encode("utf-8"))).encode()) 42 43 sleep_recv = conn.recv(1024) 44 print("缓冲...", sleep_recv.decode()) # 两条send命令可能会出现粘包的情况 45 46 conn.send(res.encode("utf-8")) 47 48 49 50 51 52 53 print("server is closed...") 54 server.close()
客户端:
1.创建client实例
2.连接服务器,地址端口
3.向服务器发送命令
4............
1 # The_author = 'liu66' 2 # By python3.x 3 # -*- coding = utf-8 -*- 4 5 6 import socket 7 8 client=socket.socket() 9 client.connect(("localhost",66)) 10 11 while True: 12 send_data=input(">>:").strip() 13 if len(send_data) == 0: continue 14 client.send(send_data.encode("utf-8")) 15 # data=client.recv(1024) 16 # print("server接收到的数据:",data.decode()) 17 18 ############ 数据初始化 #################### 19 data_size=0#要接受的数据大小 20 data_res=b''#要接受的数据的内容大小 21 received_size=0 22 received_data=b''#要接受的数据的内容 23 ############################################ 24 '''先接收要接受的数据大小''' 25 data_size=client.recv(1024) 26 print("要接受的数据大小:", data_size) 27 28 '''发送缓冲数据''' 29 client.send("...".encode()) 30 31 while received_size != int(data_size): 32 data_res=client.recv(1024) 33 received_size+=len(data_res) 34 received_data+=data_res 35 else: 36 print("已接收数据大小:",received_size) 37 print(received_data.decode("utf-8","ignore")) 38 '''decode()默认的参数就是strict,代表遇到非法字符时抛出异常; 39 如果设置为ignore,则会忽略非法字符; 40 如果设置为replace,则会用?号取代非法字符; 41 如果设置为xmlcharrefreplace,则使用XML的字符引用。''' 42 43 # print(data_res.decode("utf-8","replace")) 44 45 46 print("client is closed...") 47 client.close()
问题总结:
- 绑定地址和端口时,需要合并为一个参数
client.connect(("localhost",66))
2. 发送cmd时,判断发送的字符串不能为空
send_data=input(">>:").strip() if len(send_data) == 0: continue
3. 发送数据需要进行编码encode
client.send(send_data.encode("utf-8"))
4. 先发送需要的字符长度,再接收一个缓冲消息,最后再发送内容,防止两次连续发送的粘包
conn.send(str(len(res.encode("utf-8"))).encode()) sleep_recv = conn.recv(1024) print("缓冲...", sleep_recv.decode()) # 两条send命令可能会出现粘包的情况 conn.send(res.encode("utf-8"))
5. 执行命令异常处理
try: res = os.popen(data.decode()).read() except TypeError: print("请输入正确的CMD") else: print("------------------") print(res)#打印返回的值 print("------------------")
6. 发送ls命令不报error,返回为空,判断返回是否为空
print(len(res)) received_size='' if len(res) == 0: res = "cmd is not correct..."
7. 对于数据超过1024时处理,判断每次接受的字节长度,累加,直到长度等于发送的总长度
while received_size != int(data_size): data_res=client.recv(1024) received_size+=len(data_res) received_data+=data_res
8. print(xx.decode())经常出现非法字符异常的解决办法
print(received_data.decode("utf-8","ignore"))
'''decode()默认的参数就是strict,代表遇到非法字符时抛出异常; 如果设置为ignore,则会忽略非法字符; 如果设置为replace,则会用?号取代非法字符; 如果设置为xmlcharrefreplace,则使用XML的字符引用。'''