Python 3.7: 通过 python 套接字发送文件时出错
Python 3.7: Error while sending a file through python socket
使用Python,我想发布数据到socket。
我在 Python 3.7 中编写了一个 client/server 程序来通过网络发送一个大的 csv 文件。客户端和服务器代码如下。
示例文件:
$ cat datafile.csv
id,first_name,gender,car,money,city,country,jobtitle
1,Marline,Female,Ford,.94,Kanzaki,Japan,Food Chemist
2,Ker,Male,Lincoln,.46,Fort Beaufort,South Africa,Marketing Manager
3,Wallie,Male,Land Rover,.12,Eystur,Faroe Islands,Senior Quality Engineer
4,Deonne,Female,Ford,.72,Fontaínhas,Portugal,Social Worker
5,Barnaby,Male,Volkswagen,[=12=].60,Taoyuan,China,Web Developer I
6,Maximilian,Male,GMC,.19,Nowy Dwór Gdański,Poland,Engineer IV
7,Wake,Male,Buick,.08,Kazuno,Japan,Food Chemist
8,Truman,Male,Infiniti,.60,Içara,Brazil,Senior Quality Engineer
9,Mufi,Female,Ford,.55,Gununglajang,Indonesia,Actuary
10,Dniren,Female,Ford,.71,Yuyapichis,Peru,Software Consultant
客户端服务器程序如下:
客户代码:
$ cat client.py
import socket
HOST = 'server ip' # The remote host
PORT = 42050 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
f = open('/home/vijee/data/datafile.csv', 'rb')
print "Sending Data ...."
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
print "Sending Complete"
s.close()
服务器代码:
$ cat server.py
import socket
HOST = 'local ip' # server ip
PORT = 42050 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print "Server running", HOST, PORT
s.listen(5)
conn, addr = s.accept()
print'Connected by', addr
while True:
data = "".join(iter(lambda:conn.recv(1),"\n"))
print data
if not data: break
print "Done Receiving"
conn.close()
在执行 client.py 脚本时出现以下错误:
bash_shell:~$ python /home/vijee/data/python_code/server.py
Server running localhost 9000
Connected by ('127.0.0.1', 42950)
bash_shell:~$ python /home/vijee/data/python_code/client.py
Sending Data ....
Traceback (most recent call last):
File "/home/vijee/data/python_code/client.py", line 12, in <module>
s.send(line)
TypeError: a bytes-like object is required, not 'int'
我知道这是个小错误。但是找不到错误。
l
是一个 bytes
对象。来自 documentation:
While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integer
所以当你写 for line in l:
时,line
的每个值都是一个包含文件中单个字节的整数。 s.send()
的参数必须是 bytes
,而不是整数。所以你可以使用:
s.send(bytes([line]))
将整数转换为 bytes
对象。不要忘记 []
—— bytes
构造函数需要一个序列。如果你只写bytes(line)
,它会创建一个bytes
长度为line
的对象,内容都是零字节。
循环尝试一次发送一个字节并没有任何原因。只需使用
s.send(l)
一次发送。
顺便说一句,变量名 line
表明您认为您是逐行发送,而不是逐字节发送。那没有发生。由于您以二进制模式打开文件,因此它没有行的概念。即使您以文本模式打开它,l
也将是一个字符串,而不是一系列行;如果你想要一系列的行,你应该使用 f.readlines()
或 for line in f:
.
在 Python 3.9:
下测试
替换为:
s.send(line)
有了这个:
s.send(bytes(line, encoding="utf-8"))
使用Python,我想发布数据到socket。
我在 Python 3.7 中编写了一个 client/server 程序来通过网络发送一个大的 csv 文件。客户端和服务器代码如下。
示例文件:
$ cat datafile.csv
id,first_name,gender,car,money,city,country,jobtitle
1,Marline,Female,Ford,.94,Kanzaki,Japan,Food Chemist
2,Ker,Male,Lincoln,.46,Fort Beaufort,South Africa,Marketing Manager
3,Wallie,Male,Land Rover,.12,Eystur,Faroe Islands,Senior Quality Engineer
4,Deonne,Female,Ford,.72,Fontaínhas,Portugal,Social Worker
5,Barnaby,Male,Volkswagen,[=12=].60,Taoyuan,China,Web Developer I
6,Maximilian,Male,GMC,.19,Nowy Dwór Gdański,Poland,Engineer IV
7,Wake,Male,Buick,.08,Kazuno,Japan,Food Chemist
8,Truman,Male,Infiniti,.60,Içara,Brazil,Senior Quality Engineer
9,Mufi,Female,Ford,.55,Gununglajang,Indonesia,Actuary
10,Dniren,Female,Ford,.71,Yuyapichis,Peru,Software Consultant
客户端服务器程序如下:
客户代码:
$ cat client.py
import socket
HOST = 'server ip' # The remote host
PORT = 42050 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
f = open('/home/vijee/data/datafile.csv', 'rb')
print "Sending Data ...."
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
print "Sending Complete"
s.close()
服务器代码:
$ cat server.py
import socket
HOST = 'local ip' # server ip
PORT = 42050 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print "Server running", HOST, PORT
s.listen(5)
conn, addr = s.accept()
print'Connected by', addr
while True:
data = "".join(iter(lambda:conn.recv(1),"\n"))
print data
if not data: break
print "Done Receiving"
conn.close()
在执行 client.py 脚本时出现以下错误:
bash_shell:~$ python /home/vijee/data/python_code/server.py
Server running localhost 9000
Connected by ('127.0.0.1', 42950)
bash_shell:~$ python /home/vijee/data/python_code/client.py
Sending Data ....
Traceback (most recent call last):
File "/home/vijee/data/python_code/client.py", line 12, in <module>
s.send(line)
TypeError: a bytes-like object is required, not 'int'
我知道这是个小错误。但是找不到错误。
l
是一个 bytes
对象。来自 documentation:
While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integer
所以当你写 for line in l:
时,line
的每个值都是一个包含文件中单个字节的整数。 s.send()
的参数必须是 bytes
,而不是整数。所以你可以使用:
s.send(bytes([line]))
将整数转换为 bytes
对象。不要忘记 []
—— bytes
构造函数需要一个序列。如果你只写bytes(line)
,它会创建一个bytes
长度为line
的对象,内容都是零字节。
循环尝试一次发送一个字节并没有任何原因。只需使用
s.send(l)
一次发送。
顺便说一句,变量名 line
表明您认为您是逐行发送,而不是逐字节发送。那没有发生。由于您以二进制模式打开文件,因此它没有行的概念。即使您以文本模式打开它,l
也将是一个字符串,而不是一系列行;如果你想要一系列的行,你应该使用 f.readlines()
或 for line in f:
.
在 Python 3.9:
下测试替换为:
s.send(line)
有了这个:
s.send(bytes(line, encoding="utf-8"))