Python stream file - python

I want to stream a file (mp3) in python. I've written the server code (which doesn't work):
import socket
HOST = ''
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((HOST, PORT))
print 'Socket bind complete'
s.listen(1)
print 'Socket now listening'
conn, addr = s.accept()
data = open("song.mp3", "rb")
data = data.read()
conn.sendall(data)
I haven't written a client for it, as I wanted to make it work with VLC, Chrome and other music players. When trying in VLC it gives me a "Connection reset by peer" error, whereas in Chrome it gives a "Broken pipe" error.
What I'm trying to do is make a basic replica of AirPlay, but I don't know what's wrong.

Have a look at this
Playing remote audio files in Python?
The mp3 format was designed for streaming, which makes some things simpler than you might have expected. The data is essentially a stream of audio frames with built-in boundary markers, rather than a file header followed by raw data, have a look at following url for more information.
Writing a Python Music Streamer

OK, I got it to work with VLC by using HTTP here's the code:
import socket
filePath = "/storage/sdcard0/Music/song.mp3"
fileData = open(filePath, "rb").read()
host = ''
port = 8808
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HTTPString = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: audio/mpeg\r\n\r\n" + fileData
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
conn.sendall(HTTPString)
UPDATE: Got it to work with Chrome's (never thought I'd say this) stupid persistent connections, which raise SIGPIPE, so I just ignore it:
import socket
filePath = "/storage/sdcard0/Music/Madonna - Ray Of Light.mp3"
fileData = open(filePath, "rb").read()
host = ''
port = 8808
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HTTPString = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: audio/mpeg\r\n\r\n" + fileData
s.bind((host, port))
s.listen(10)
while 1:
try:
conn, addr = s.accept()
conn.sendall(HTTPString)
except socket.error, e:
pass

Related

Python Sockets: Client and Server both sending and receiving data from each other?

How can I get a socket to send data and then receive data? I followed some tutorials online and can get a server to send data to a client. My goal is to send a pickled image from the client to the server and then have the server respond with a text. Could someone provide a quick example of this bi-directional communication?
I don't know what you mean exactly by bi-directional communication or pickled image, but I can provide you with a sample tcp socket code to send an image. Skip to the full code section for the code you seek, which is at the bottom.
Here is a server example:
import socket
# next create a socket object
s = socket.socket()
print("Initialized socket")
port = 8986
print("Port set to:" + str(port))
s.bind(('', port))
s.listen(5)
print("socket is waiting for client")
while True:
c, addr = s.accept()
print('Client', addr )
# send a thank you message to the client.
c.send('Demo'.encode())
c.close()
and then a client sample will be like:
import socket
s = socket.socket()
print("Initialized socket")
port = 8986
print("Port set to:" + str(port))
s.connect(('127.0.0.1', port))
print(s.recv(1024).decode() )
s.close()
Now to send to send an image you'll need read the image with pythons functions as a byte array and send it.
#On server-side
def read(self, filename):
toRead = open(filename, "rb")
out = toRead.read()
toRead.close()
return out
imgData = read("demo.jpg")
c.send(imgData)
On client-side:
imgData = s.recv(1024)
def write(self, filename, data):
toWrite = open(filename, "wb")
out = toWrite.write(data)
toWrite.close()
write("Demo.jpg", imgData)
Full Code Server socket:
import socket
def read(filename):
toRead = open(filename, "rb")
out = toRead.read()
toRead.close()
return out
imgData = read("demo.jpg")
# next create a socket object
s = socket.socket()
print("Initialized socket")
port = 8986
print("Port set to:" + str(port))
s.bind(('', port))
s.listen(5)
print("socket is waiting for client")
while True:
c, addr = s.accept()
print('Client', addr )
print("Sending image")
c.send(imgData)
print(c.recv(1024).decode())
#c.close()
Full client-code:
import socket
def write(filename, data):
toWrite = open(filename, "wb")
out = toWrite.write(data)
toWrite.close()
s = socket.socket()
print("Initialized socket")
port = 8986
print("Port set to:" + str(port))
s.connect(('127.0.0.1', port))
#The buffer size is important to set correctly.
#Below buffersize is 1024*8 which is about 8kB.
#Images more than 8kB will appear to be cut from the top.
#To prevent this you have to set a higher buffersize.
#Or you can have the server socket send the image length before
#sending the image byte-array.
imgData = s.recv(1024*8)
write("Demo.jpg", imgData)
s.send("Received image".encode())
s.close()

Getting error non-blocking (10035) error when trying to connect to server

I am trying to simply send a list from one computer to another.
I have my server set up on one computer, where the IP address is 192.168.0.101
The code for the server:
import socket
import pickle
import time
import errno
HEADERSIZE = 20
HOST = socket.gethostbyname(socket.gethostname())
PORT = 65432
print(HOST)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
while True:
conn, adrs = s.accept()
print(f"Connection with {adrs} has been established")
conn.setblocking(1)
try:
data = conn.recv(HEADERSIZE)
if not data:
print("connection closed")
conn.close()
break
else:
print("Received %d bytes: '%s'" % (len(data), pickle.loads(data)))
except socket.error as e:
if e.args[0] == errno.EWOULDBLOCK:
print('EWOULDBLOCK')
time.sleep(1) # short delay, no tight loops
else:
print(e)
break
The client is on another computer. The code:
import socket
import pickle
HOST = '192.168.0.101'
PORT = 65432
def send_data(list):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
print(".")
print(s.connect_ex((HOST, PORT)))
print(".")
data = pickle.dumps(list)
print(len(data))
s.send(data)
s.close()
send_data([1,1,1])
The outputted error number of connect_ex is 10035. I read a lot about the error, but all I found was about the server side. To me, it looks like the problem is with the client and that it is unable to make a connection to 192.168.0.101. But then, I don't understand why the error I get is about non-blocking.
What is it that I am doing wrong that I am unable to send data?
First of all, how user207421 suggested, change the timeout to a longer duration.
Also, as stated here Socket Programming in Python raising error socket.error:< [Errno 10060] A connection attempt failed I was trying to run my server and connect to a private IP address.
The fix is: on the server side, in the s.bind, to leave the host part empty
HOST = ''
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
And on the client side, use the public IP of the PC where the server is running (I got it from ip4.me)
HOST = 'THE PUBLIC IP' #not going to write it
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, PORT))

TCP client server not receiving any data from each other

I have written the following TCP client and server using python socket module. However, after I run them, no output is being given. It seems that
the program is not able to come out of the while loop in the recv_all method
Server:
import socket
def recv_all(sock):
data = []
while True:
dat = sock.recv(18)
if not dat:
break
data.append(dat)
return "".join(data)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = '127.0.0.1'
PORT = 45678
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen(1)
print "listening at", sock.getsockname()
while True:
s, addr = sock.accept()
print "receiving from", addr
final = recv_all(s)
print "the client sent", final
s.sendall("hello client")
s.close()
Client :
import socket
def recv_all(sock):
data=[]
while True:
dat=sock.recv(18)
if not dat:
break
data.append(dat)
return "".join(data)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
PORT=45678
HOST='127.0.0.1'
sock.connect((HOST,PORT))
sock.sendall("hi server")
final=recv_all(sock)
print "the server sent",final
Because in server file you use an endless loop in another. I suggest you to edit recv_all method in both files this way:
def recv_all(sock):
data = []
dat = sock.recv(18)
data.append(dat)
return "".join(data)
But after edit like this your server stays on until KeyInterrupt, while you should run client file everytime you want to send data. If you want an automatically send/receive between server and client, I offer you try threading.

How to download file from local server in Python

Scenario is:
Client will Enter a file name e.g xyz
Server will show all the files that it have in different folders.
Client will select 1 or 2 or 3 (if there).
and file will be downloaded.
I have done searching part. I want help in downloading and saving the file in any other directory.
My code so far is for searching the file.
import socket
tcp_ip="127.0.0.1"
tcp_port=1024
buffer_size= 200
filename=raw_input("Enter file name\n")
s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((tcp_ip,tcp_port))
data=s.recv(buffer_size)
s.close()
Server Code : (This code is now for one file) The required help is how to download and save that file which is found at server.
import socket
import os
tcp_ip='127.0.0.1'
tcp_port=1024
buffer_size=100
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((tcp_ip, tcp_port))
s.listen(1)
conn, addr = s.accept()
print 'Connection Address:',addr
while 1:
data=conn.recv(buffer_size)
if not data:
break
else:
print "received server side data:", data
conn.send(data)
conn.close()
Following is the example which shows how to download a file from a server over tcp.
Client Code:
import socket
import os
HOST = 'localhost'
PORT = 1024
downloadDir = "/tmp"
filename = raw_input('Enter your filename: ')
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(filename)
with open(os.path.join(downloadDir, filename), 'wb') as file_to_write:
while True:
data = socket1.recv(1024)
if not data:
break
file_to_write.write(data)
file_to_write.close()
socket1.close()
Server Code:
import socket
HOST = 'localhost'
PORT = 1024
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((HOST, PORT))
socket.listen(1)
while (1):
conn, addr = socket.accept()
reqFile = conn.recv(1024)
with open(reqFile, 'rb') as file_to_send:
for data in file_to_send:
conn.sendall(data)
conn.close()
socket.close()
Note: server code is not robust and will crash when file doesn't exists. You should modify above example according to your needs.

client-server chat python error

I'm trying the following client and server chat program. Although I get an error whenever I try to run the server program, when the client program runs it stays on a blank screen not allowing me to type anything. I've tried running server first and running client first and I get the same results. I can't read the error from the server program because it flashes the error and closes the window. Here is my code:
server:
#server
import socket
import time
HOST = ''
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
client:
#client
import socket
import time
HOST = "localhost"
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((HOST,PORT))
s.sendall('Helloworld')
data = s.recv(1024)
s.close()
print 'Recieved', repr(data)
Im not an expert but I was able to make your examples work by changing the socket from datagram to stream connection, and then encoding message being sent because strings aren't supported (although this might not effect you since I think that change was made in Python 3...I'm not 100% sure).
I believe the main issue is that you're trying to listen() but SOCK_DGRAM (UDP) doesn't support listen(), you just bind and go from there, whereas SOCK_STREAM (TCP) uses connections.
If you're just trying to get the program going, use the below code, unless there is a specific reason you'd like to use SOCK_DGRAM.
The code is below:
client
#client
import socket
import time
HOST = "localhost"
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
test = 'Helloworld'
s.sendall(test.encode())
data = s.recv(1024)
s.close()
print 'Recieved', repr(data)
server
#server
import socket
import time
HOST = ''
PORT = 8065
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,PORT))
s.listen(1)
conn, addr = s.accept()
print ('Connected by', addr)
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()

Categories