Python 3.7: ошибка при отправке файла через сокет python - PullRequest
0 голосов
/ 09 июля 2019

Используя Python, я хочу опубликовать данные в сокет.
Я написал клиент-серверную программу на Python 3.7 для отправки большого CSV-файла по сети.Коды клиента и сервера приведены ниже.

Пример файла:

$ cat datafile.csv
id,first_name,gender,car,money,city,country,jobtitle
1,Marline,Female,Ford,$4.94,Kanzaki,Japan,Food Chemist
2,Ker,Male,Lincoln,$3.46,Fort Beaufort,South Africa,Marketing Manager
3,Wallie,Male,Land Rover,$5.12,Eystur,Faroe Islands,Senior Quality Engineer
4,Deonne,Female,Ford,$9.72,Fontaínhas,Portugal,Social Worker
5,Barnaby,Male,Volkswagen,$0.60,Taoyuan,China,Web Developer I
6,Maximilian,Male,GMC,$1.19,Nowy Dwór Gdański,Poland,Engineer IV
7,Wake,Male,Buick,$5.08,Kazuno,Japan,Food Chemist
8,Truman,Male,Infiniti,$1.60,Içara,Brazil,Senior Quality Engineer
9,Mufi,Female,Ford,$7.55,Gununglajang,Indonesia,Actuary
10,Dniren,Female,Ford,$7.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'

Я знаю, что это маленькая ошибка.Но не смог найти ошибку.

1 Ответ

2 голосов
/ 09 июля 2019

l является bytes объектом. Из документации :

В то время как байтовые литералы и представления основаны на тексте ASCII, байтовые объекты фактически ведут себя как неизменяемые последовательности целых чисел

Поэтому, когда вы пишете for line in l:, каждое значение line является целым числом, содержащим один байт из файла. Аргумент g к s.send() должен быть bytes, а не целым числом. Таким образом, вы можете использовать:

s.send(bytes([line]))

для преобразования целого числа в bytes объект. Не забывайте, что [] - конструктор bytes ожидает последовательность. Если вы просто напишите bytes(line), он создаст объект bytes, длина которого равна line, а все содержимое равно нулю байтов.

На самом деле нет никаких причин для цикла, который пытается посылать по одному байту за раз. Просто используйте

s.send(l)

чтобы отправить все сразу.

Кстати, имя переменной line предполагает, что вы думаете, что вы отправляете построчно, а не побайтно. Этого не происходит Поскольку вы открыли файл в двоичном режиме, он не имеет понятия строк. И даже если бы вы открыли его в текстовом режиме, l была бы строкой, а не последовательностью строк; если вы хотите последовательность строк, вы должны использовать f.readlines() или for line in f:.

...