python socket server in Heroku - python

Im trying to deploy a server using the socket module to heroku. The server runs correctly when I look at the logs from heroku, the problem is that i have not been able to connect to it with the client and it seems that an ip address is constantly connecting to the server.
Procfile: web: python Server.py
The server I built has this structure.
import socket
import os
from _thread import start_new_thread
PORT = int(os.environ(['PORT']))
HOST = '0.0.0.0'
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.bind((HOST, PORT))
except socket.error as e:
pass
s.listen(2)
def threaded_client(conn):
print(f'CONNECTED -> {conn}')
while True:
# some logic
pass
if __name__== '__main__':
while True:
conn, addr = s.accept()
start_new_thread(threaded_client, (conn,))
And the client.
import socket
PORT = 80
HOST = 'https://my-heroku-app.herokuapp.com'
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((HOST,PORT))
I have a similar issue as the one mentioned in here
Any insight would be appreciated. Thanks

you can't use heroku to host a tcp server ,you need a service like linode https://www.linode.com/ ,or aws ,but you can use heroku to host a websocket server which you can use a python websocket client to connect to ,like so
from websocket import create_connection
ws = create_connection("ws://myapp.herokuapp.com")
print("Sending 'Hello, World'...")
ws.send("Hello, World")
print("Sent")
print("Receiving...")
result = ws.recv()
print("Received '%s'" % result)
ws.close()

Related

Heroku: ErrorTimeout connecting to a socket

I'm having problems with a simple socket connection to an Heroku app.
This is my server:
import socket
import os
import time
import sys
server = socket.socket()
port = int(os.environ.get("PORT", 12344))
host = "0.0.0.0"
server.bind((host, port))
print(f"###### SERVER RUNNING ON PORT {port} ({host}) ######")
server.listen()
while True:
s, addr = server.accept()
print("Recived request from:", addr)
print(addr, " sent: ", repr(s.recv(1024)))
print("Answering to:", addr)
s.send("Hello, world! (from server)".encode())
print("Answered to:", addr)
s.close()
It builds and run perfectly on Heroku(it receives also socket connection, not from me...by at this time, I don't care much about it)
This is my client:
import socket
import sys
HOST = 'app_name.herokuapp.com/' # The server's hostname or IP address
PORT = int(sys.argv[1]) # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("connecting to " + HOST +":"+str(PORT))
s.connect((HOST, PORT))
print(s)
s.sendall("HI!!!".encode())
data = s.recv(1024)
print('Received', repr(data))
Running the client, after a while it returns:
File "./client.py", line 14, in <module>
s.connect((HOST, PORT))
TimeoutError: [Errno 110] Connection timed out
I don't know how to connect to it...am I missing something?
The problem is linked to the fact that Heroku app allow only http(s) connections. I honesty didn't found any Heroku docs that conferm it but the Daniel Chin' answer to this question make sense to me.
However, move the server.py to AWS worked for me (EC2 with t2.micro is free for the first year!!)

Python3 NAT hole punching

I know this topic is not new. There is various information out there although, the robust solution is not presented (at least I did not found). I have a P2P daemon written in python3 and the last element on the pie is to connect two clients behind the NAT via TCP. My references for this topic:
https://bford.info/pub/net/p2pnat/
How to make 2 clients connect each other directly, after having both connected a meeting-point server?
Problems with TCP hole punching
What I have done so far:
SERVER:
#!/usr/bin/env python3
import threading
import socket
MY_AS_SERVER_PORT = 9001
TIMEOUT = 120.0
BUFFER_SIZE = 4096
def get_my_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return bytes(IP, encoding='utf-8')
def wait_for_msg(new_connection, client_address):
while True:
try:
packet = new_connection.recv(BUFFER_SIZE)
if packet:
msg_from_client = packet.decode('utf-8')
client_connected_from_ip = client_address[0]
client_connected_from_port = client_address[1]
print("We have a client. Client advertised his local IP as:", msg_from_client)
print(f"Although, our connection is from: [{client_connected_from_ip}]:{client_connected_from_port}")
msg_back = bytes("SERVER registered your data. Your local IP is: " + str(msg_from_client) + " You are connecting to the server FROM: " + str(client_connected_from_ip) + ":" + str(client_connected_from_port), encoding='utf-8')
new_connection.sendall(msg_back)
break
except ConnectionResetError:
break
except OSError:
break
def server():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((get_my_local_ip().decode('utf-8'), MY_AS_SERVER_PORT))
sock.listen(8)
sock.settimeout(TIMEOUT)
while True:
try:
new_connection, client_address = sock.accept()
if new_connection:
threading.Thread(target=wait_for_msg, args=(new_connection,client_address,)).start()
# print("connected!")
# print("")
# print(new_connection)
# print("")
# print(client_address)
msg = bytes("Greetings! This message came from SERVER as message back!", encoding='utf-8')
new_connection.sendall(msg)
except socket.timeout:
pass
if __name__ == '__main__':
server()
CLIENT:
#!/usr/bin/python3
import sys
import socket
import time
import threading
SERVER_IP = '1.2.3.4'
SERVER_PORT = 9001
# We don't want to establish a connection with a static port. Let the OS pick a random empty one.
#MY_AS_CLIENT_PORT = 8510
TIMEOUT = 3
BUFFER_SIZE = 4096
def get_my_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return bytes(IP, encoding='utf-8')
def constantly_try_to_connect(sock):
while True:
try:
sock.connect((SERVER_IP, SERVER_PORT))
except ConnectionRefusedError:
print(f"Can't connect to the SERVER IP [{SERVER_IP}]:{SERVER_PORT} - does the server alive? Sleeping for a while...")
time.sleep(1)
except OSError:
#print("Already connected to the server. Kill current session to reconnect...")
pass
def client():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
#sock.bind((get_my_local_ip().decode('utf-8'), MY_AS_CLIENT_PORT))
sock.settimeout(TIMEOUT)
threading.Thread(target=constantly_try_to_connect, args=(sock,)).start()
while True:
try:
packet = sock.recv(BUFFER_SIZE)
if packet:
print(packet)
sock.sendall(get_my_local_ip())
except OSError:
pass
if __name__ == '__main__':
client()
Now the current code results:
./tcphole_server.py
We have a client. Client advertised his local IP as: 10.10.10.50
Although, our connection is from: [89.22.11.50]:32928
We have a client. Client advertised his local IP as: 192.168.1.20
Although, our connection is from: [78.88.77.66]:51928
./tcphole_client1.py
b'Greetings! This message came from SERVER as message back!'
b'SERVER registered your data. Your local IP is: 192.168.1.20 You are connecting to the server FROM: 89.22.11.50:32928'
./tcphole_client2.py
b'Greetings! This message came from SERVER as message back!'
b'SERVER registered your data. Your local IP is: 10.10.10.50 You are connecting to the server FROM: 78.88.77.66:51928'
As you can see the server has all information to connect two clients. We can send details about the other peer individually through the current server-client connection.
Now two questions remain in my head:
Assuming the SERVER sends information about CLIENT 1 and CLIENT 2 for each of the peers. And now the CLIENTS starts connecting like [89.22.11.50]:32928 <> [78.88.77.66]:51928 Does the SERVER should close the current connections with the CLIENTS?
How the CLIENT Router behaves? I assume it expecting the same EXTERNAL SERVER SRC IP [1.2.3.4], instead gets one of the CLIENTS EXT IP for instance [89.22.11.50] or [78.88.77.66]?
This is messier than I thought. Any help to move forward appreciated. Hope this would help other Devs/DevOps too.
Finally found the expected behavior! Don't want to give too much code here but I hope after this you will understand the basics of how to implement it. Best to have a separate file in each of the client's folder - nearby ./tcphole_client1.py and ./tcphole_client2.py. We need to connect fast after we initiated sessions with the SERVER. Now for instance:
./tcphole_client_connector1.py 32928 51928
./tcphole_client_connector2.py 51928 32928
Remember? We need to connect to the same ports as we initiated with SERVER:
[89.22.11.50]:32928 <> [78.88.77.66]:51928
The first port is needed to bind the socket (OUR). With the second port, we are trying to connect to the CLIENT. The other CLIENT doing the same procedure except it binds to his port and connects to yours bound port. If the ROUTER still has an active connection - SUCCESS.

SOCKET PROGRAMMING PYTHON- Putting the server code on an online server

So I have a Client - Server code in python and its running perfectly on LAN. I have this server setup on AWS and I have uploaded my server code there. In my client code, I have changed the host to the ip-address of the server online.
Unfortunately when I run the server code then the client code, there is no connection established. What could be the issue ??
Here is a part of client code:
def starting_client():
sckt = socket.socket()
host = '172.31.32.226'
port = 9090
sckt.connect((host, port))
while True:
data = sckt.recv(1024) #Data received from the server
try:
Here is part of Server code:
def SeverSocket():
try:
global host
global port
global sckt
host = ''
port = 9090
sckt = socket.socket()
except socket.error as scktCreationErrorMsg:
print(f"An error was encountered during Socket Creation: {scktErrorMsg}")
else:
print("\033[34mSocket was created as succesfull\033[0m")

Socket server in python refuses to connect

I am trying to create a simple web server with python using the following code.
However, When I run this code, I face this error:
ConnectionRefusedError: [WinError 10061] No connection could be made
because the target machine actively refused it
It worths mentioning that I have already tried some solutions suggesting manipulation of proxy settings in internet options. I have run the code both in the unticked and the confirmed situation of the proxy server and yet cannot resolve the issue.
Could you please guide me through this ?
import sys
import socketserver
import socket
hostname = socket.gethostname()
print("This is the host name: " + hostname)
port_number = 60000
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((hostname,port_number))
Standard EXAMPLE of socket connection
SERVER & CLIENT
run this in your IDLE
import time
import socket
import threading
HOST = 'localhost' # Standard loopback interface address (localhost)
PORT = 60000 # Port to listen on (non-privileged ports are > 1023)
def server(HOST,PORT):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while True:
conn, addr = s.accept()
data = conn.recv(1024)
if data:
print(data)
data = None
time.sleep(1)
print('Listening...')
def client(HOST,PORT,message):
print("This is the server's hostname: " + HOST)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((HOST,PORT))
soc.send(message)
soc.close()
th=threading.Thread(target = server,args = (HOST,PORT))
th.daemon = True
th.start()
After running this, in your IDLE execute this command and see response
>>> client(HOST,PORT,'Hello server, client sending greetings')
This is the server's hostname: localhost
Hello server, client sending greetings
>>>
If you try to do server with port 60000 but send message on different port, you will receive the same error as in your OP. That shows, that on that port is no server listening to connections

The socket server on ubuntu can't be connected

the code of socket-server and the code of socket-client can run perfectly on my localhost, but when I run the code of socket-server on Ubuntu server, the code of socket-client on my localhost can't connect to Ubuntu server.And the code of socket-client on Ubuntu Server can't connect to my localhost Server.
socket-server.py
import socket
import threading
def bbs(conn):
user_list.append(conn)
try:
while 1:
msg = conn.recv(1024)
if msg:
for user in user_list:
user.send(msg)
except ConnectionResetError:
user_list.remove(conn)
conn.close()
user_list = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 18000))
server.listen()
while 1:
conn, addr = server.accept()
t = threading.Thread(target=bbs, args=(conn,))
t.start()
socket-client.py
import socket
import threading
import time
def send_msg():
while 1:
msg = input()
client.send((name + ':' + msg).encode('utf-8'))
def recv_msg():
while 1:
msg = client.recv(1024)
if msg:
try:
print(msg.decode('utf-8'))
time.sleep(1)
except UnicodeDecodeError:
pass
name = input('请输入你的昵称:')
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.26.8.132', 18000))
sendmsg_thread = threading.Thread(target=send_msg)
recvmsg_thread = threading.Thread(target=recv_msg)
sendmsg_thread.start()
recvmsg_thread.start()
Server is always wait for connection, Client report an error:
TimeoutError: [WinError 10060] The connection attempt failed because the connecting party did not respond correctly after a period of time or because the connecting host did not respond.
Wang if this works without issue on your localhost, but not over a network connection, it might be a firewall issue on both client & server. You can use 'nc' (netcat) for testing the connection from client to the server.

Categories

Resources