3

I am trying to send UDP video packets using sockets in Python.

The Server IP address is :192.168.67.14

The Client IP address is 192.168.67.42

The Client and Server can ping each other. Below is the code used for establishing the socket:

Server Side:

import urllib, time, os, m3u8
from socket import *
# Socket initialization
s = socket(AF_INET, SOCK_DGRAM)
host = "192.168.67.42"
port = 5000
buf = 1024
addr = (host, port)
s.connect((host, port))
ts_filenames = []
while True:
 playlist = "https://sevenwestmedia01-i.akamaihd.net/hls/live/224853/TEST1/master_lowl.m3u8"
 m3u8_obj = m3u8.load(playlist)
 ts_segments = m3u8_obj.__dict__.values()[6]
 ts_segments_str = str(m3u8_obj.segments)
 for line in ts_segments_str.splitlines():
 if "https://" in line:
 ts_id = line[-20:]
 if ts_id not in ts_filenames:
 print ts_id
 ts_filenames.append(ts_id)
 try:
 ts_segment = urllib.URLopener()
 ts_segment.retrieve(line, ts_id)
 except:
 pass
 f = open(ts_id, "rb")
 data = f.read(buf)
 while (data):
 if (s.sendto(data, addr)):
 print "sending ..."
 data = f.read(buf)

Client Side

import socket 
s = socket.socket() 
host = '192.168.67.14' 
port = 5000 
s.connect((host,port))
print s.recv(1024)
s.close

Exception I get:

Traceback (most recent call last): File "client.py", line 7, in s.connect((host,port)) File "/usr/lib/python2.7/socket.py", line 228, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 111] Connection refused

I spent some time looking into this discussion but I still not sure what to modify. Any suggestions please ?

asked Dec 23, 2016 at 15:03

2 Answers 2

3

You have multiple problems here. First, by using connect on the server end, you're telling the operating system that you will only be communicating with IP address "192.168.67.42" port 5000. That is probably not what you intended. (A server usually talks to whatever client wants to talk to it.)

Second, by not specifying SOCK_DGRAM in your client, you're getting the default socket type, which is SOCK_STREAM. That means your client is trying to connect to your server on TCP port 80 -- not UDP port 80 (the two namespaces are totally separate).

For a UDP "session", both sides need an IP address and a port number. If you do not bind a port specifically, the operating system will choose one for you quasi-randomly. In order to link up client and server, they must agree on at least one of those.

So a typical UDP server will bind to a well-known port (presumably you intended 5000 for that purpose). Then the client can connect to the server at that port. The code would look something like this (sans error handling):

Server side:

# Create socket
s = socket(AF_INET, SOCK_DGRAM)
# Bind to our well known port (leave address unspecified 
# allowing us to receive on any local network address)
s.bind(('', 5000))
# Receive from client (so we know the client's address/port)
buffer, client_addr = s.recvfrom(1024) 
# Now we can send to the client
s.sendto(some_buffer, client_addr)

The client is close to what you have, but you should send some data from the client to the server first so that the server knows your address:

s = socket(AF_INET, SOCK_DGRAM)
# Create connection to server (the OS will automatically 
# bind a port for the client)
s.connect((host, port))
# Send dummy data to server so it knows our address/port
s.send(b'foo')
buffer = s.recv(1024)

Note that because you have used connect on the client side, you've permanently specified your peer's address and don't need to use recvfrom and sendto.

answered Dec 23, 2016 at 15:32
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the suggestions: now I get no connection errors and I can capture the traffic on the client interface...But how can I verify that the client is actually receiving the traffic ? In the client there is a print s.recv(1024) but nothing shows in terminal
Sounds like the server datagrams are not getting to the client? In the client, after the connect, print the value of s.getsockname(). In the server, after it's done recvfrom, print the value of client_addr. Those should match. If they do, sendto should be able to deliver data back to the client at that address. If still not working, not sure what to advise: maybe use tcpdump or wireshark to see what the packets "on the wire" look like.
2

On the client side, this is wrong:

s = socket.socket() 

for receiving UDP packets, you need to create a UDP socket, same as you did on the server side:

s = socket(AF_INET, SOCK_DGRAM)

Also, if you want your client to be able to receive UDP packets you will need to bind() it to port 5000 (connect() is neither necessary nor sufficient for that).

answered Dec 23, 2016 at 15:25

3 Comments

Thanks for the suggestion: I modified the client to be s = socket(AF_INET, SOCK_DGRAM) and now it doesn't give me an exception...Now the server is giving me the following exception: Traceback (most recent call last): File "decryptvideo.py", line 43, in <module> if (s.sendto(data, addr)): socket.error: [Errno 111] Connection refused
The interesting thing is that the client is listening now on port 5000 netstat | grep 5000 udp 0 0 192.168.67.42:59249 192.168.67.14:5000 ESTABLISHED
Note my final paragraph about the necessity of calling bind() in order to receive packets on a port.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.