Sashaank
Sashaank

Reputation: 964

how to correct zmq address in use error with django

I am trying to create a simple video streaming site with Django. I am using cv2 for starting the webcam and ZMQ for transferring data from client to server. I found this link with which I wrote the networking part of the code.

The code by itself works fine, but when I create a simple HTML file to start the live stream through the browser the code fails with this error message

zmq.error.ZMQError: Address in use

I guess this error arises because the IP Django uses and the IP ZMQ tries to uses is the same. But I am not sure how to rectify this error.

This is my code so far

server.py

def start_server():
    context = zmq.Context()
    footage_socket = context.socket(zmq.SUB)
    print('socket created')

    footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
    footage_socket.bind('tcp://192.168.1.18:5020')

    print('binding complete')
    print('server ready')

    return footage_socket

def recv_content(socket, face_cascade_path):

    cascade = cv2.CascadeClassifier(face_cascade_path)

    while True:
        try:
            data = socket.recv_string()
            img = base64.b64decode(data)
            npimg = np.fromstring(img, dtype=np.uint8)
            frame = cv2.imdecode(npimg, 1)
            print(frame)

            face = cascade.detectMultiScale(frame, scaleFactor=1.3, minNeighbors=3)

            for (x, y, w, h) in face:
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            cv2.imshow("Stream", frame)

        except KeyboardInterrupt:
            cv2.destroyAllWindows()
            break

views.py

from server import *

def index(request):

    face_cascade_path = '../../../TRAINED MODELS/FACE/haarcascade_frontalface_default.xml'
    footage_socket = start_server()
    recv_content(footage_socket, face_cascade_path)

    return render(request, 'index.html')

def start_client(request):
    context = zmq.Context()
    footage_socket = context.socket(zmq.PUB)
    footage_socket.connect('tcp://192.168.1.18:5020')

    print('connected to server')
    print('starting video on client machine')

    camera = cv2.VideoCapture(0)  # init the camera

    while True:
        try:
            grabbed, frame = camera.read()  # grab the current frame
            frame = cv2.resize(frame, (640, 480))  # resize the frame
            frame = cv2.flip(frame, 1)
            encoded, buffer = cv2.imencode('.jpg', frame)
            jpg_as_text = base64.b64encode(buffer)
            footage_socket.send(jpg_as_text)

        except KeyboardInterrupt:
            camera.release()
            cv2.destroyAllWindows()
            break

index.html

<html>
<head>

</head>
<body>
  <div class='container'>
    <h2>CAMERA SERVER CLIENT TEST</h2>

    <p>
    Click the start_client button to start camera. Each frame of the stream is sent to the server.
    </p>
    <p>
      The camera code is running on the client side.
    </p>

    <a href ='start_client/'><button>start client</button></a>

  </div>
</body>
</html>

Please help me.

Thank you in advance

EDIT 1 - I have edited to add the client part of the code and index.html as well. The start_client function is under views.py. This function is run when the start_client button in index.html is clicked

EDIT 2 - I have edited the question to add a screenshot of my problem. While I dont face the "address in use" error when I refresh the page after adding the try-except block, the webpage is still not loading.

enter image description here

Upvotes: 1

Views: 789

Answers (1)

Benyamin Jafari
Benyamin Jafari

Reputation: 34086

You should adopt another port instead of the common 8000 port which usually is in use.

Another idea is that any socket options must be placed before bind or connect method in ZMQ.

So your code will look something like this:

def start_server():
    context = zmq.Context()
    footage_socket = context.socket(zmq.SUB)
    footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))

    try:
        footage_socket.bind('tcp://192.168.1.18:5020')  # Another port used.
    except:
        pass

    return footage_socket

[NOTE]:

Do not forget to change the port on the client side (.connect()) to 5020.


[UPDATE]:

Upvotes: 1

Related Questions