python search string from socket - python

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)

Related

What's the best way to reassemble bytes sent from client to server?

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.

how to fix sending string with python socket after sending a file

i am trying to make a server and client which sends a file from client to server and the server saves it to hard then the server asks for another file and if the answer of client is yes then the client sends the second file then the server again saves it and if the client answer is no server close the socket when i run this code the first file is sent
and received successfully but after that both of the server and the client freeze and nothing happens what is wrong with it and how can i fix it?
my server code:
import socket
host = 'localhost'
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
(client, (ip, port))=s.accept()
while True:
data = "".join(iter(lambda: client.recv(1), "\n"))
with open('filehere.txt', 'w') as file:
for item in data:
file.write("%s" % item)
if not data: break
client.send("is there any other file?")
d = client.recv(2048)
if d == "yes":
while True:
data = "".join(iter(lambda: client.recv(1), "\n")
with open('filehere1.txt', 'w') as file:
for item in data:
file.write("%s" % item)
if not data: break
s.close()
else:
s.close()
my client code:
import socket
host = 'locahost'
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
f = open('myfile.txt', 'rb')
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
d = s.recv(2048)
a = raw_input(d)
if a == "yes":
s.send("yes")
f = open('myfile1', 'rb')
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
else:
s.close
Why did you check a == "yes" on client side even when server is not sending "yes"
I think you can check a == "is there any other file?" insted

TCP Client retrieving no data from the server

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")
......

audio over python tcp error

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.

condition from UDP data doens't work in PYTHON

I would like to make condition from datas from UDP with Python.
here's my code:
import socket
import atexit
UDP_IP = "127.0.0.1"
UDP_PORT = 8002
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print("listen to port: " + str(UDP_PORT))
while True:
data, addr = sock.recvfrom(1024)
data = data.rsplit(",")
data = data.pop(0)
print(data)
if data=='1':
print("BOOL is TRUE")
"BOOL is true should be printed when data==1, but nothing occurs...
Any clue ? Thanks in advance.
Try replacing this line:
data = data.pop(0)
with this:
data = data.pop(0).strip('\x00')
This will remove the NULLs that are padding the string.
Alternatively, you could look into why the values are being NULL padded and fix it on the server side.

Categories