I am trying to receive data from a TCP Server in python. I try to open a file at the server and after reading its content, try to send it to the TCP Client. The data is read correctly from the file as I try to print it first on the server side but nothing is received at the Client side.
PS. I am a beginner in network programming.
Server.py
import socket
import os
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5000))
server_socket.listen(5)
client_socket, address = server_socket.accept()
print ("Conencted to - ",address,"\n")
data = client_socket.recv(1024).decode()
print ("Filename : ",data)
fp = open(data,'r')
string = fp.read()
fp.close()
print(string)
size = os.path.getsize(data)
size = str(size)
client_socket.send(size.encode())
client_socket.send(string.encode())
client_socket.close()
Client.py
import socket,os
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("", 5000))
size = 1024
print ("Your filename : \n")
string = input()
client_socket.send(string.encode())
size = client_socket.recv(1024).decode()
print ("The file size is - ",size[0:2]," bytes")
size = int(size[0:2])
string = client_socket.recv(size).decode()
print ("\nFile contains : ")
print (string)
client_socket.close();
Try:
#Get just the two bytes indicating the content length - client_socket.send(size.encode())
buffer = client_socket.recv(2)
size = len(buffer)
print size
print ("The file size is - ",buffer[0:2]," bytes")
#Now get the remaining. The actual content
print buffer.decode()
buffer = client_socket.recv(1024)
size = len(buffer)
print size
print buffer.decode()
Add Accept() in while loop as below.
while True:
client_socket, address = server_socket.accept()
print ("Conencted to - ",address,"\n")
......
Related
What's the best way to stream bytes from client to server in chunks of determined size?
Right now I'm encoding an audio file with base64, then compressing it with zlib and sending through the socket connection. My problem is trying to rebuild the original within the server.
I thought and tested using an empty string that is added with all the bytes the server is receiving. Seemed alright, but the " b' " in the beginning was being kept, which left it unable to recover the original audio file.
I've just tried to decode the bytes and deleting the " b' " from the beginning and " " " from the end (data[2:-1]) of each set of strings received by the server, but this cut a few characters from the original.
client side:
with open(arquivo, 'rb') as input_file:
abc = base64.b64encode(input_file.read())
try1 = zlib.compress(abc)
n = 338
result = [try1[i:i+n] for i in range(0, len(try1), n)]
HOST = ''
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((HOST,PORT))
i = 0
for item in result:
item = str(item)
print(item)
s.send(item.encode())
i += 1
print('i = ', i)
time.sleep(2)
Server side:
HOST = ''
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print('Servidor Inicializado')
s.bind((HOST,PORT))
s.listen()
audiofile = ''
i = 0
conn, addr = s.accept()
while True:
data1 = conn.recv(2048)
print('data1 undecoded = ', data1)
text = data1.decode()
data = text[2:-1]
print('data EDITADO = ', data)
audiofile = audiofile + data
i += 1
print('i = ', i)
print('audiofile = ', audiofile)
if not data:
print('No Data Received!')
print('Recebeu tratado :', data)
No idea how to proceed, any help is appreciated. Thanks!
Here is an example of how I send and receive data with sockets.
Typically I'll pickle them. If you're not familiar with pickle it's used to serialize python objects to store or send over connections such as sockets.
Client Side:
import pickle
with open(arquivo, 'rb') as input_file:
abc = base64.b64encode(input_file.read())
# I haven't used these libraries so I'm assuming you know how to unpack it from here
try1 = zlib.compress(abc)
HOST = ''
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((HOST,PORT))
# serialize the python object
message = pickle.dumps(try1)
# get the length of the pickled object
length = len(message)
# convert into a fixed width string
length = str(length).rjust(8, '0')
# send the length of the object we will send
s.sendall(bytes(length, 'utf-8'))
# send the object
self.client.sendall(message)
Server Side:
import pickle
HOST = ''
PORT = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST,PORT))
s.listen()
conn, addr = s.accept()
# get the length of the object we are about to receive
length = conn.recv(8)
# turn it back into an int
length = int(length.decode('utf-8'))
# I keep this to determine if we've received everything or not
full_length = length
message = None
# loop until we've zeroed out our length
while length > 0:
# only receive what we need
# at a maximum of 128 bit chunks
chunk_len = min(128, length)
length -= chunk_len
chunk = conn.recv(chunk_len)
if message is None:
message = chunk
else:
message = message + chunk
# Edit: I've had issues with slow connections not receiving the full data
# for those cases adding something like this works
while len(message) < full_length:
chunk_len = min(128, full_length - len(message))
chunk = conn.recv(chunk_len)
message = message + chunk
# now that we've received everything, we turn it back into a python object
try1 = pickle.loads(message)
# this should be the same try1 you sent
Disclaimer: I did not test any of this, nor do I know what the try1 object is or what you want to do with it. this is just getting it from point a to point b.
I have been able to receive the file from the socket and download it, but when I try to push a message from the server to the client the message is never displayed on the client side.
Below is the code and any help would be highly appreciated as I am a novice to network programming.
# get the hostname
host = socket.gethostname()
port = 5000 # initiate port no above 1024
Buffer = 1024
server_socket = socket.socket() # get instance
# look closely. The bind() function takes tuple as argument
server_socket.bind((host, port)) # bind host address and port together
# configure how many client the server can listen simultaneously
server_socket.listen(2)
conn, address = server_socket.accept() # accept new connection
print("Connection from: " + str(address))
f = open("FileFromServer.txt", "wb")
# receive data stream. it won't accept data packet greater than 1024 bytes
data = conn.recv(Buffer)
while data:
f.write(data)
print("from connected user: " + str(data))
data = conn.recv(Buffer)
f.close()
print 'Data Recivede'
datas = 'Recived the file Thanks'
if datas is not '':
conn.send(datas) # send data to the client
conn.close() # close the connection
host = socket.gethostname() # as both code is running on same pc
port = 5000 # socket server port number
client_socket = socket.socket() # instantiate
client_socket.connect((host, port)) # connect to the server
with open('T.txt', 'rb') as f:
print 'file openedfor sending'
l = f.read(1024)
while True:
client_socket.send(l)
l = f.read(1024)
f.close()
print('Done sending')
print('receiving data...')
data = client_socket.recv(1024)
print data
client_socket.close() # close the connection
print 'conection closed
The thing is that you both you server and client socket stuck in the while loop:
try this client.py:
import socket
host = socket.gethostname() # as both code is running on same pc
port = 5000 # socket server port number
client_socket = socket.socket() # instantiate
client_socket.connect((host, port)) # connect to the server
end = '$END MARKER$'
with open('T.txt', 'rb') as f:
print('file opened for sending')
while True:
l = f.read(1024)
if len(l + end) < 1024:
client_socket.send(l+end)
break
client_socket.send(l)
print('Done sending')
print('receiving data...')
data = client_socket.recv(1024)
print(data)
client_socket.close() # close the connection
print('conection closed')
server.py
import socket
# get the hostname
host = socket.gethostname()
port = 5000 # initiate port no above 1024
Buffer = 1024
end = '$END MARKER$'
server_socket = socket.socket() # get instance
# look closely. The bind() function takes tuple as argument
server_socket.bind((host, port)) # bind host address and port together
# configure how many client the server can listen simultaneously
server_socket.listen(2)
conn, address = server_socket.accept() # accept new connection
print("Connection from: " + str(address))
# receive data stream. it won't accept data packet greater than 1024 bytes
with open("FileFromServer.txt", "ab") as f:
while True:
data = conn.recv(Buffer)
if end in data:
f.write(data[:data.find(end)])
conn.send(b'Recived the file Thanks')
break
f.write(data)
conn.close()
I am writing a simple python tcp code to send over a wav file however I seem to be getting stuck. can someone explain why my code is not working correctly?
Server Code
import socket, time
import scipy.io.wavfile
import numpy as np
def Main():
host = ''
port = 3333
MAX = 65535
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
print "Listening on port..." + str(port)
c, addr = s.accept()
print "Connection from: " + str(addr)
wavFile = np.array([],dtype='int16')
i = 0
while True:
data = c.recvfrom(MAX)
if not data:
break
# print ++i
# wavfile = np.append(wavfile,data)
print data
timestr = time.strftime("%y%m%d-%h%m%s")
print timestr
# wavF = open(timestr + ".wav", "rw+")
scipy.io.wavfile.write(timestr + ".wav",44100, data)
c.close()
if __name__ == '__main__':
Main()
Client Code
host, port = "", 3333
import sys , socket
import scipy.io.wavfile
# create a tcp/ip socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect the socket to the port where the server is listening
server_address = (host, port)
print >>sys.stderr, 'connecting to %s port %s' % server_address
input_data = scipy.io.wavfile.read('Voice 005.wav',)
audio = input_data[1]
sock.connect(server_address)
print 'have connected'
try:
# send data
sock.sendall(audio)
print "sent" + str(audio)
sock.close()
except:
print('something failed sending data')
finally:
print >>sys.stderr, 'closing socket'
print "done sending"
sock.close()
Please help someone, I want to send an audio file to my embedded device with tcp since it crucial data to be processed on the embedded device.
Not sure why you go to the trouble of using scipy and numpy for this, since you can just use the array module to create binary arrays that will hold the wave file. Can you adapt and use the simple client/server example below?
(Note: I've copy/pasted a small Windows sound file called 'tada.wav' to the same folder to use with the test scripts.)
Code for the server script:
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
print('Listening...')
conn, addr = s.accept()
print('Connected by', addr)
outfile = open("newfile.wav", 'ab')
while True:
data = conn.recv(1024)
if not data: break
outfile.write(data)
conn.close()
outfile.close()
print ("Completed.")
Code for the client:
from array import array
from os import stat
import socket
arr = array('B') # create binary array to hold the wave file
result = stat("tada.wav") # sample file is in the same folder
f = open("tada.wav", 'rb')
arr.fromfile(f, result.st_size) # using file size as the array length
print("Length of data: " + str(len(arr)))
HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(arr)
print('Finished sending...')
s.close()
print('done.')
This works for me (though only tested by running both on localhost) and I end up with a second wave file that's an exact copy of the one sent by the client through the socket.
I have the following text file:
ADDRESS1 192.168.124.1
ADDRESS2 192.168.124.2
ADDRESS3 192.168.124.3
And I wrote the following string server in python (strsrv.py) :
#!/usr/bin/env python
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(backlog)
while 1:
global f
client, address = s.accept()
data = client.recv(size)
with open('list.txt', 'r') as my_file:
for f in my_file.readlines():
if(f.find('%s' % data)>-1):
data = f
if f:
client.send(data)
client.send(f)
client.close()
I'm trying to connect to this server sending a string. This string must match one of lines described on text file. Ex: sending 'ADDRESS1' should return 'ADDRESS1 192.168.124.1' from the server, but it doesn't works. Any string sent returns only the last line of the text file. Please could someone point me to the right direction? Thanks :)
How are you testing this? Assuming you open a socket and connect to the host you should see that you are in fact receiving the correct line as well as the last one. Why? Because in the for loop you keep changing the value of f, the last value of f will be the last line in the file, and you send it back after sending data (which at that point is the correct value).
Here's a suggestion for how you might modify your code (assuming you want the full line back and you dont want wildcarding):
#!/usr/bin/env python
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(backlog)
# build dict of addresses first, no need to do this for each message
with open('list.txt', 'r') as my_file:
address_map = dict(line.split() for line in my_file)
while True:
client, address = s.accept()
req_address = client.recv(size)
ip = address_map.get(req_address, 'Not found')
client.send(req_address + ' ' + ip)
client.close()
You can simply test this by doing this while the above is running:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('', 50000))
s.send('ADDRESS2')
s.recv(1024)
I am trying to receive an image in python to use it in my program.
Here is the sever code:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("127.0.0.1", 5005))
server_socket.listen(5)
data = ' '
client_socket, address = server_socket.accept()
print "Conencted to - ",address,"\n"
while (1):
data = client_socket.recv(1024)
print "The following data was received - ",data
print "Opening file - ",data
img = open(data,'r')
while True:
strng = img.readline(512)
if not strng:
break
client_socket.send(strng)
img.close()
print "Data sent successfully"
exit()
#data = 'viewnior '+data
#os.system(data)
And here is the client code:
import socket,os
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("127.0.0.1", 5005))
size = 1024
while(1):
print "Enter file name of the image with extentsion (example: filename.jpg,filename.png or if a video file then filename.mpg etc) - "
fname = raw_input()
client_socket.send(fname)
#fname = 'documents/'+fname
fp = open(fname,'w')
while True:
strng = client_socket.recv(512)
if not strng:
break
fp.write(strng)
fp.close()
print "Data Received successfully"
exit()
#data = 'viewnior '+fname
#os.system(data)
The received should now be read to be able to use it. I am opening it like this:
input_image = Image.open('data').convert('L').resize((100, 100))
but when I run both codes in cmd the output is:
The following data was received - + path Opening file - + path
Then nothing happens although the image should be used and the final output should be shown.
Anyone can help?
I don't know if this is your (only) problem, but when working with binary files, you should pass the b flag to the built-in function open:
img = open(data, 'rb')