Server implementation with python socket and port forwarding - python

I've been trying to implement a server-client connection, here is my code-
Server.py
import socket
server = socket.socket()
server.bind(('', 2112))
server.listen(5)
print('Server created with port 2112')
server.accept()
print('Connected')
Client.py
import socket
##Public_IP is the Public IP address of my router
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((Public_IP, 2112))
Both Server.py and Client.py are running on my computer(server). It works just fine when I replace Public_IP with '192.168.0.143', but when I use Public_IP, it gives the following error-
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Is it because I'm running both Server.py and Client.py on the same computer? Please let me know what I'm doing wrong.
Setting up port forwarding -
Public IP
Port forwarding
Private IP address of server
I followed this tutorial for setting up port forwarding.
I also tried replacing the empty string in Server.py with my private IP address-
server.bind(('192.168.0.143', 2112))
Edit: I have tried-
Running Client.py externally (on a different LAN) with firewall down on both the ends, but didn't make any difference (it gave a timeout error).
Running Client.py on the same LAN with firewall down, that seemed to work fine.
Running the Client.py on the same device also worked fine with the firewall down.

Related

Create TCP Server accessible on remote networks

A project I am working on has an Android app as a front-end and a Python program that would be used as the back-end.
I want to send data from the Android app (primarily images) to the Python program, do some processing and send the result back to the Android app.
I have found numerous tutorials that suggest using the socket module in python to create the server side, but all tutorials show the server on local network only (For testing purposes I created the client side also in Python, but it would be converted to Java later on)
The server code:
from requests import get
import socket
public_ip = get('https://api.ipify.org').text
print('My public IP address is: {}'.format(public_ip))
# getting the hostname by socket.gethostname() method
hostname = socket.gethostname()
# getting the IP address using socket.gethostbyname() method
local_ip = socket.gethostbyname(hostname)
# printing the hostname and ip_address
print(f"Hostname: {hostname}")
print(f"IP Address: {local_ip}")
#
HOST = local_ip
PORT = 80 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024).decode('utf-8')
if not data:
break
conn.sendall(data.encode('utf-8'))
The client code:
import socket
HOST = '…' # I modify it to the server's public IP address, as printed from the server code
PORT = 80 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
with socket.create_connection((HOST, PORT)) as s:
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
Using the code above, if I try using any port other than 80 I get ConnectionRefusedError: [Errno 111] Connection refused. And for port 80, I get TimeoutError: [Errno 110] Connection timed out.
In both cases, I try to connect from a device on another network.
I tried to use the ping command in Windows CMD to check the connection to the server, and I get 'connection refused message'.
I understand that the Firewall is what probably blocks the connection, but I don't know how to bypass it. I added a new rule in the Inbound Rules section (as suggested on other websites) but for no avail… The results were the same.
How can I make the connection between remote devices on different networks?
Thanks in advance ☺
In order to connect to your server using a TCP socket connection, you need to make sure your server can listen on a port on a publically available IP address.
If the External IP address is assigned to your computer directly,
and if you run the server code on that computer, then the TCP port opened by the server code should be available on the internet.
However, IP addresses are often assigned to a modem/router in home networks,
instead of assigning them to any connected device directly.
To find out if your External IP address is assigned to the computer directly you can use tools that your OS support (eg. ipconfig on windows). If you can see the IP address returned by api.ipify.org, then it means your computer is connected directly. You can change your code to connect using publically exposed IP:
HOST = public_ip
If this is successful means your computer is assigned an external address directly. Which is highly unlikely.
There are several workarounds for this problem though:
1) Configure your router to forward port
Configure your router to forward all connections to it's external TCP port, to an internal host in your network which is assigned to your computer. Please find instructions how it is done for your router.
2) Setup a remote proxy
If you don't have permission to change your router settings you can set up a remote proxy listening on the TCP port. While there is a number of ways of doing this, very popular is to set up a remote SSH tunnel, for that you need to have a server with SSH access and an external IP. Run this command:
ssh -R 80:localhost:8080 root#your-ssh-server-host
You can also use a third-party service that exposes your private host on the internet like:
Ngrok (Commercial, with free plans)
Localtunnel (Open Source, can be self-hosted)

TCP Socket not connecting [WinError 10060] - Python

I'm making a chat app using sockets in python, but when I try to connect from a different computer then it says:
C:\Users\James\OneDrive\Documents\Python\Projects\Gui Chat\client.pyw
[WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
This is the server code for the socket:
host = socket.gethostbyname(hostname)
port = 55555
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
print(f"IP: {server.getsockname()[0]}\nPORT: {server.getsockname()[1]}")
server.listen()
I also have a while True loop accepting all requests:
while True:
client, address = server.accept()
print(f"Connected with {str(address)}")
On the client end this is the socket code:
IP = simpledialog.askstring("IP", "Enter IP address", parent=root) # "192.168.1.252" # input("Enter IP: ")
nickname = simpledialog.askstring("Nickname", "Choose a nickname", parent=root)
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client.connect((IP, 55555))
except Exception as e:
print(e)
The programme asks for the IP address each time, and when I put in the correct IP for the server computer, it comes up with the error above. It works if I try to connect from the same computer, and they are both on the same network. It was working recently, and now it has just stopped working.
UPDATE:
I have set the server ip to 0.0.0.0, I have set up a port forwarding rule, I have checked the firewall and allowed incoming and outgoing connections, and I have run nmap with these results:
Code issues
First try binding server on localhost or 127.0.0.1.
FireWall/Ports issues
Check if your computer's default computer/antivurus
firewall (where server is hosted) allow connections
on your port 55555.
And if computer with client is outside your home network
point to router public IP address and make sure you have
port forwarding setup on router.
Address issues
Are you sure that IP you are writing in client is correct.
Go to your computer with server and check that IP.
Windows:
Go to cmd or Power Shell and type ipconfig, then find
section IPv4 Address and look that address you habe there.
Linux / MacOS
Go to your terminal and type ifconfig -a, and
it should be somewhere there, but I don't have those systems,
so I can't test it for you. If it does't work try to search how to
find that out.

Remote connection not working. Couldn't connect to server with python socket

[WinError 10061] and [WinError 10060]. These are the errors im getting when i send a client app to my friend. Remotely it just doesn't work. Locally it works fine. Can i get a full explanation step by step please cause i couldn't find any soulution and i'm getting mad.
SERVER:
import socket as s
HOST = 'ppp.ppp.p.ppp'
PORT = 33000
server_socket = s.socket(s.AF_INET, s.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()
while True:
client_socket, address = server_socket.accept()
print(f'Connected {address}')
CLIENT:
import socket as s
HOST = 'ppp.ppp.p.ppp'
PORT = 33000
client_socket = s.socket(s.AF_INET, s.SOCK_STREAM)
client_socket.connect((HOST, PORT)) # here is error
PS: CLIENT GETS ERRORS NOT SERVER
welcome to SO. You and your friend are probably not on the same network. Therefore, when sending a connection request, your router (or your friends) does not know to relay the packet to the correct device in it's network. There are multiple things you need to do:
Make sure that the IP is not your local network IP but rather the IP of your router. check on wahtismyip. Use that as the ip. Note that the ip will change every so often.
Then, the difficult part. You need to tell your router (or your friends if the server is in his network) to relay the packets arriving at port 33000 to the server. This is different from device to device, try googling "Port forwarding ".
Hopefully this resolves your issues.

How to connect two computers using python socket without local connection

Im using python socket to connect two computers,
it completely works when both systems are connected to one mobile hotspots or LAN,
But when i use two diffrent hotspots or try to connect to my friend's PC, it stops working and client cant find server.
(I find my IP using "ipconfig" command on cmd from "Wireless LAN adapter Wi-Fi: IPV4 Adress")
here are my codes for checking the connection:
#SERVER
import socket
s = socket.socket()
IP, port= MY IP, 8002
s.bind((IP,port))
while 1:
s.listen(1)
a,b=s.accept()
print(a,b)
print("client tried to connect")
#Client
import socket
s=socket.socket()
IP,port=SERVERS IP, 8002
s.connect((IP,port))
Can you guys help me please?

Python socket timing out on other computer. TimeoutError: [WinError 10060]

I'm trying to connect a client to server through python sockets. Clients connect successfully on my computer, but people on other networks cannot connect.
TimeoutError: [WinError 10060]
on the client side after failing to connect. Here is the code for my python scripts.
Server.py
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "0.0.0.0"
port = 8000
print (host)
print (port)
serversocket.bind((host, port))
Client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "##.###.###.###" # server's public ip.
port = 8001
s.connect((host,port))
print("Connected to server.")
s.send(("Client connected").encode())
The ports are different because I can't connect without the local and external ports being different on my router; local being 8000 and external being 8001. If the client is on my computer, the server reveals it's being connected to by the public ip, so it's passing through my router.
Doing nmap -p 8000 -sN -P0 192.168.0.# on my server computer, reveals the port is closed using http-alt. Doing it on my public ip reveals that it's open|filtered using vcom-tunnel, but it's open|filtered on almost every port.
What I have tried:
Port forwarding with local_port=8000 and remote_port=8001. External ip set to my public ip, and my local ip set to my computer ip; 192.168.0.#
Using DMZ Host (Exposed Host) on server-side router.
Enabling and disabling UPNP, WAN Blocking, Ipsec PassThrough & PPTP PassThrough separately on server-side router.
Allowing TCP port 8000, on local and remote through server-side firewall.
Allowing program through firewall on public & private networks on client and server.
Allowing TCP port 8001, on local and remote through client-side firewall.
Binding client ip with socket.bind((client_ip,port)) on client.py
It might be the port I'm using having to do with http-alt/vcom-tunnel, instead of one with upnp.
The problem was setting the external ip on my port forward to my public ip. What ip it was set to, it was only scanning for my ip, which let to only my computer being able to connect to it. I set the external ip to 0.0.0.0, making the port open to all ips.

Categories