Python: Socket.error Connection Refused in Unix [Errno 111]

pythonsockets

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 ?

Best Answer

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.

Related Topic