'Python 3.7: Error while sending a file through python socket
Using Python, I want to publish data to socket.
I written a client/server program in Python 3.7 to send a large csv file over the network. The client and server codes are given below.
Sample file:
$ 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
Below are the client server program:
Client code:
$ 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()
Server code:
$ 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()
While executing client.py script I am getting the below error:
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'
I know it is small mistake. But could not able to find the error.
Solution 1:[1]
l is a bytes object. From the documentation:
While bytes literals and representations are based on ASCII text, bytes objects actually behave like immutable sequences of integer
So when you write for line in l:, each value of line is a integer containing a single byte from the file. The argumentg to s.send() has to be bytes, not an integer. So you could use:
s.send(bytes([line]))
to convert the integer to a bytes object. Don't forget the [] -- the bytes constructor expects a sequence. If you just write bytes(line), it will create a bytes object whose length is line and the contents are all zero bytes.
There's not really any reason for the loop that tries to send one byte at a time. Just use
s.send(l)
to send it all at once.
BTW, the variable name line suggests that you think you're sending line by line, not byte by byte. That's not happening. Since you opened the file in binary mode, it doesn't have the notion of lines. And even if you'd opened it in text mode, l would be a string, not a sequence of lines; if you want a sequence of lines you should use f.readlines(), or for line in f:.
Solution 2:[2]
Tested under Python 3.9:
Replace this:
s.send(line)
With this:
s.send(bytes(line, encoding="utf-8"))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Contango |
