人过留名,雁过留声。
人生天地间,凡有大动静处,必有猪头。
问题
初学 python 网络编程,使用 socket 模块,创建客户端和服务端两个脚本进行输局传输的时候,出现错误 TypeError: a bytes-like object is required, not ‘str’ 或者将接收的数据打印出来时出现这样的格式: b’内容’ 。
解决
数据传输时是传输比特流,在 python 3 中使用 recv() 函数接受的是数据的比特流形式,在打印出来时要解码( decode() )转换为字符串;同样的,在传输数据时,要编码( encode() )转换为比特流在发送才不会报错。
转换形式
b = b"example" # bytes object
s = "example" # str object
sb = bytes(s, encoding = "utf8") # str to bytes
或者:sb = str.encode(s) # str to bytes
bs = str(b, encoding = "utf8") # bytes to str
或者:bs = bytes.decode(b) # bytes to str
源码
下面是我在学习过程采用的源码,可以实现客户端和服务端交互,同时在服务端也设置了一个小后门。
客户端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket # 导入 socket 模块
c = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口号
c.connect((host, port))
while 1:
res = c.recv(1024)
res = res.decode()
print('service: ',res)
x = input('client: ')
x = x.encode()
c.send(x)
服务端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket,os # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口
s.bind((host, port)) # 绑定端口
s.listen(5) # 等待客户端连接
while True:
c,addr = s.accept() # 建立客户端连接
lan = 'welcome zhutou!'
c.send(lan.encode())
while 1:
res = c.recv(1024)
res = res.decode()
if res == 'cmd' :
result = 'ok'
c.send(result.encode())
res = c.recv(1024)
res = res.decode()
x = os.popen(res).read()
x = x.encode()
c.send(x)
else:
print ('client: ',res)
str = input('service: ')
str = str.encode() #python的bytes和str两种类型转换的函数encode()、decode()即可!
c.send(str)
结果
先运行服务端脚本,再运行客户端脚本
猪头
2020.1.13