python video streaming display packets - python

I am working on a Networks course project, in which I have to create a video streaming server. I found this link for a simple python client/server socket binary stream that seems quite useful. I am able to send video files as packets over the network, but the receiving side is saving the incoming packets as a file. I would like to display the incoming packets as a video stream (preferably on a web browser using HTML), instead of writing to a file. Please suggest some possible method of doing this. Thanks.
As I am doing a project, I would like to create a streaming server from scratch rather than use existing implementations like Flumotion.
Here's the code for the sending and receiving sides:
Sending side:
import socket
HOST = 'localhost'
PORT = 9876
ADDR = (HOST,PORT)
BUFSIZE = 4096
videofile = "./test2.mp4"
bytes = open(videofile).read()
print len(bytes)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
client.send(bytes)
client.close()
Receiving side:
import socket
HOST = ''
PORT = 9876
ADDR = (HOST,PORT)
BUFSIZE = 4096
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv.bind(ADDR)
serv.listen(5)
print 'listening ...'
while True:
conn, addr = serv.accept()
print 'client connected ... ', addr
myfile = open('testfile.mov', 'w')
while True:
data = conn.recv(BUFSIZE)
if not data: break
myfile.write(data)
print 'writing file ....'
myfile.close()
print 'finished writing file'
conn.close()
print 'client disconnected'

Related

Sending a file over TCP connection

I want to send i file over TCP but when i try to run this the connection fails, the server receives the file but it gives this error: ERROR: Client timed out before sending a file
import selectors
import sys
from socket import *
import sock
sel1 = selectors.DefaultSelector()
print(len(sys.argv), sys.argv[1], sys.argv[2], sys.argv[3])
host = sys.argv[1]
port = int(sys.argv[2])
file = sys.argv[3]
try:
# Instaniating socket object
s = socket(AF_INET, SOCK_STREAM)
# Getting ip_address through host name
host_address = gethostbyname(host)
# Connecting through host's ip address and port number using socket object
s.connect((host_address, port))
sel1.register(
sock,
selectors.EVENT_READ, data = None)
fileToSend = open("file.txt", "rb")
data = fileToSend.read(1024)
while data:
print("Sending...")
fileToSend.close()
s.send(b"Done")
print("Done Sending")
print(s.recv(1024))
s.shutdown(2)
s.close()
except:
# Returning False in case of an exception
sys.stderr.write("Connection Failed")
Do the writing in a loop. There's no particular reason to chop it into 1024-byte pieces; the network stack will handle that for you.
By the way, your "Done" signal is not a good idea, especially since you're writing a binary file that might very well contain the word "Done". Remember that TCP is a streaming protocol. The other end does not see the exact packets you're sending. That is, just because you send 1024 bytes and 4 bytes, the other end might see it as reads of 256 and 772 bytes.
# Instaniating socket object
s = socket(AF_INET, SOCK_STREAM)
# Getting ip_address through host name
host_address = gethostbyname(host)
# Connecting through host's ip address and port number using socket object
s.connect((host_address, port))
fileToSend = open("file.txt", "rb")
print("Sending...")
while True:
data = fileToSend.read(1024)
if not data:
break
s.send( data )
fileToSend.close()
s.send(b"Done")
print("Done Sending")
print(s.recv(1024))
s.close()

Unable to use sockets to send data over the internet in python

I am trying to write a script to transmit an image over the internet using sockets (the code is shown below). When I try it on the local machine the code works fine but when I do the same with 2 different computers (1 working as a server and 1 as client) connected to the same WiFi network, they don't even connect to one another let alone transmit data. Can anyone please help?
The server code :-
import socket
import base64
import sys
import pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 8487))
s.listen(5)
while True:
# After the Connection is established
(clientsocket, address) = s.accept()
print(f"Connection form {address} has been established!")
# Initiate image conversion into a string
with open("t.jpeg", "rb") as imageFile:
string = base64.b64encode(imageFile.read())
msg = pickle.dumps(string)
print("Converted image to string")
# Send the converted string via socket encoding it in utf-8 format
clientsocket.send(msg)
clientsocket.close()
# Send a message that the string is sent
print("String sent")
sys.exit()
The client code :-
import socket, pickle, base64
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 8487))
while True:
data = []
# Recieve the message
while True:
packet = s.recv(1000000)
if not packet:
break
data.append(packet)
print("Message recieved")
# Decode the recieved message using pickle
print("Converting message to a String")
string = pickle.loads(b"".join(data))
print("Converted message to String")
# Convert the recieved message to image
imgdata = base64.b64decode(string)
filename = 'tu.jpeg'
with open(filename, 'wb') as f:
f.write(imgdata)
s.shutdown()
s.close()
s.connect((socket.gethostname(), 8487))
Your client attempts to connect to the local host. If the server host is the local host this works. But if the server host is different this will of course not connect to the server. Instead you have to provide the IP address or hostname of the servers system here.

Why Python Socket works only on local network?

I'm trying to send a text file trhough Python sockets and it works but only on local network. Why is that?(I'm working with Python 3.6)
This is the server.py:
import socket
HOST = '0.0.0.0'
PORT = 80
ADDR = (HOST,PORT)
BUFSIZE = 4096
print(socket.gethostbyname(socket.gethostname()))
serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serv.bind(ADDR)
serv.listen(5)
print ('listening ...')
while True:
conn, addr = serv.accept()
print ('client connected ... ', addr)
myfile = open('asd.txt', 'w')
while True:
data = conn.recv(BUFSIZE)
if not data: break
myfile.write(data.decode("utf-8"))
print ('writing file ....')
myfile.close()
print ('finished writing file')
conn.close()
print ('client disconnected')
This is the client.py:
import socket
HOST = '192.168.2.109'
PORT = 80
ADDR = (HOST,PORT)
BUFSIZE = 4096
textfile = "C:/Users/Public/asd.txt"
bytes = open(textfile, "r").read()
print (len(bytes))
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect_ex(ADDR)
client.send(bytes.encode())
client.close()
I've tried this and it worked on local network, but when I sent to my friend the client to try it, it just printed out the bytes but didn't connect to my server.(The server was running on my pc)
If the client and host are connected to the same network(LAN) i.e through same router or a hotspot, then the above code will work. If you want to do something like, run server.py on a PC connected to your WiFi and run client.py on a laptop connected through dongle you will have to use port-forwarding.

How do you send a dictionary over a socket in Python?

I know that similar questions have been raised but they don't seem to work for me! I have tried serializing the dictionary then converting that to a string then encoding it before I send it over the socket. No success so far!
This is my server code:
#library
import socket
import pickle
#socket initialization
host = "127.0.0.1"
port = 5000
mainAddr = (host, port)
#dict initialization
dataDict = {} #just imagine that dict has content
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.bind((mainAddr))
s.listen(4)
print('program started')
print('listening..')
while True:
try:
conn, addr = s.accept()
print("connection from: "+str(addr))
print("sending message..")
pickle.dumps(dataDict)
print('pickled!')
dataS = str(dataP)
print('stringed!')
dataE = dataS.encode('UTF-8')
print('encoded!')
s.sendto(dataE,addr)
print('data sent!')
except:
pass
s.close()
For the socket initialization, I've tried other types:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
s = socket.socket()
For the sending part, I've tried these alternatives:
s.send(dataE)
s.send(dataE,addr)
s.sendall(dataE)
s.sendall(dataE,addr)
When I run the program, these get printed out:
program started
listening..
connection from:<insert addr here>
sending message..
pickled!
stringed!
encoded!
Only data sent! is not sent. So I am guessing that it's the sending part that has a problem.
For the client side, here's the code:
#library
import socket
import pickle
#initialization
host = '127.0.0.1'
port = 5000
buffer = 1024
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.connect((host,port))
print('connected!')
#receive dictionary
print('receiving message..')
while True:
data, addr = s.recvfrom(buffer)
print('received!')
dataD = data.decode("UTF-8")
print('decoded!')
dataP = pickle.loads(dataD)
print('unpickled!')
print(str(dataP))
s.close()
In the client terminal, only the following prints:
connected!
receiving message..
On the client side, I've tried changing the order of unpickling and decoding but still, to no avail.
A TCP server socket is not actually used for sending/receiving data; I'm surprised you're not getting an error when calling s.send() or similar on it. Instead, it's a factory for producing individual sockets for each client that connects to the server - conn, in your code. So, conn.sendall() is what you should be using. No address parameter is required, the individual socket already knows who it is talking to. (.send() is unreliable without some extra work on your part; .sendto() is only used with UDP sockets that have not been connected to a particular client.)

python udp server parse and send received data to MySQL

i am working on some proof of concept study research project and have python udp socket server that listen received data.
Client send data NAME and FAMILY NAME on UDP to server.
I would like to receive that data on UDP socket server side and on receive send this data to mysql database with two fields f_name and l_name.
import socket
UDP_IP = "192.168.1.10"
UDP_PORT = 9000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print "UDP SERVER STARTED!"
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "MSG Received:", data
this example is taken from web and with this server i get data on console.
I would like to have it like below and of course code/concept can be changed. This might be solved with scapy sniffer but that would be dirty.
Conceptually i would like to have ti something like:
1. socekt server received data
2. parse data received and send this data to mysql
I started with this in mind but doesnt work
import socket
import MySQLdb
UDP_IP = "192.168.1.10"
UDP_PORT = 9000
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
print "UDP SERVER STARTED!"
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
def parse(data):
db = MySQLdb.connect("localhost","db_user","db_pass","directory_db")
cursor = db.cursor()
# Params to insert into DB
f_nameObj = re.search(r'NAME: (.*?) .*', data, re.M|re.I)
if f_name:
f_name = f_nameObj.group(1)
l_nameObj = re.search(r'SURNAME: (.*?) .*', data, re.M|re.I)
if l_name:
l_name = l_nameObj.group(1)
# MySQL EXECUTION
cursor.execute("""
INSERT INTO dictionary (f_name, l_name) VALUES (%s, %s)""",(f_name,l_name))
#
db.commit()
With this kind of udp server i see no messages so seems function that parse data is not working with server.
Any help or guidance would be appreciated
In your server when you receive data you don't call parse function.You just print the content of data. Add the line with the comment and see the result.
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
parse(data) # Call the Function

Categories