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.
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:
.