user3126264
user3126264

Reputation:

How to run a python Flask and TCP server in same app

In the code below I believe I'm able to get a TCP server running alongside a Flask app, but I'm getting a "ConnectionRefusedError 61" when I run a test client app that just connects and listens.

I also receive errors if I let the flask app run, and then click one of my form buttons, saying that "conn is not defined".

Ultimate goal: To have a Flask app that can send messages to another computer on our network with TCP or Websockets. The reason I'm trying TCP first is firstly familiarity compared to Websockets, and secondly I couldn't find a flask Websockets framework that was Python 3 compatible, and everything we do is in Python 3, so if I can avoid managing 2 versions of Python, that would be one less thing to think about. I'm open to alternative suggestions.

Client and server code below:

Server:

from flask import Flask, render_template, request
import random, socket, threading

#tcp server
TCP_IP = '127.0.0.1'
TCP_PORT = 7005
BUFFER_SIZE  = 20

def launchServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((TCP_IP, TCP_PORT))
    s.listen(1)

    print('waiting for connection')
    conn, addr = s.accept()

    print ('Connection address:', addr)


#flask app
app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':    
        if request.form['submit'] == 'button1':
            conn.send(b'button1')
            return "Random number between 1 and 10:  " + str(random.randint(1,10))
        elif request.form['submit'] == 'button2':
            conn.send(b'button1')
            return "Random number between 11 and 1000:  " + str(random.randint(11,1000))
        else:
            pass

    if request.method == 'GET':
        return '''
        <title>What would you like to do?</title>
        <form action="" method="post">
        <br><br>
        <input type="submit" name="submit" value="button1">
        <br><br>
        <input type="submit" name="submit" value="button2">
        </form>
        '''

if __name__ == "__main__":
    app.run(debug=True)
    t = threading.Thread(target=launchServer)
    t.daemon = True
    t.start()

Client app:

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 7004
BUFFER_SIZE = 20

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((TCP_IP, TCP_PORT))

while 1:
    data = s.recv(BUFFER_SIZE)
    if not data: break
    print ('received data: ', data)

s.close()

Upvotes: 5

Views: 13537

Answers (3)

Shabab Ayub
Shabab Ayub

Reputation: 11

'127.0.0.1' means local computer. The client app is connecting to itself, not the server. You need the server's IP. Refer to this:

Python ConnectionRefusedError: [Errno 61] Connection refused

Also the variable "conn" is used in index() but it's instantiated in launchServer(). This won't work because it's out of scope.

Upvotes: 1

Jas
Jas

Reputation: 337

Try changing:

app.run(debug=True)
t = threading.Thread(target=launchServer)
t.daemon = True
t.start()

To:

t = threading.Thread(target=launchServer)
t.daemon = True
t.start()
app.run(debug=True)

so that the server actually gets to start on the other thread.

Upvotes: 2

Meng Wang
Meng Wang

Reputation: 277

Build an RESTfuul API on the flask website, then other program can easily communicate with http. For example, python has requests library for this. This is a easier way.

Upvotes: 0

Related Questions