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

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.

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)

Server implementation with python socket and port forwarding

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.

Why is my client only working on my computer but not on any other computer

I am currently trying to learn how servers and clients work by making a trojan using python and sockets import, my client and server work perfectly on my computer but the moment I send the client to my other laptop the server does not connect. This happens even when i am on the same wifi network.
Server:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = ''
port = 1234
server.bind((host, port))
server.listen(5)
run = True
client, addr = server.accept()
print('Got connection from',addr)
while run:
try:
data = input('>>>')
client.send(data.encode('UTF-8'))
msg = client.recv(1024)
print(msg.decode('UTF-8'))
except ConnectionResetError:
print('Client lost server connection')
print('Trying to connect . . .')
client, addr = server.accept()
print('Got connection from',addr)
Client:
import socket
import os
server = socket.socket()
host = '127.0.0.1'
port = 1234
run = True
server.connect((host,port))
while run:
msg = server.recv(1024)
os.popen(msg.decode('UTF-8'))
server.send('Client online . . .'.encode('UTF-8'))
Your client is connecting to IP 127.0.0.1 (the IPv4 loopback address), which will work only when the server is on the same machine as the client.
When the client and server are on different machines, but still on the same LAN network, the client needs to connect to the server's LAN IP instead. Use netstat or similar tool on the server machine to find its LAN IP. Or, simply have your server code print out its local IPs.
When the client is on another network, it needs to connect to the public WAN IP of the server's LAN router, and that router needs to have port forwarding configured on it to route incoming connections from its WAN IP/Port to the server's LAN IP/port. To get the WAN IP, you will have to look at your router's config, or simply query an external site, like https://api.ipify.org, https://api.my-ip.io/ip, etc from a machine on the LAN, like your server.
Update your client to take in the target host/IP from user input, then it will be able to handle all of these scenarios without having to use different code each time.

Python: Connect using sockets via external IP

Today, I have made my very first sockets program - I made a client and a server that message each other (kind of like a chat) using sockets. When using the internal IP as 'host', The connection is established, otherwise using the external IP, no connection is established.
Edit 1:
#Client
s = socket.socket()
host = '123.123.123.123'
port = 9999
s.connect((host, port))
#Server
host = ''
port = 9999
s = socket.socket()
s.bind((host, port))
s.listen(5)
connection, address = s.accept()
How will this work properly with, for example, a laptop? Since your IP changes each time you switch Wifi, how would I be able to create a program that would permanently work with this specific laptop?
I understand that I have to port-forward the specific port to a specific internal machine such as 192.168.0.5. but what if I'm using a laptop and I don't have access to the WIFI router. I wouldn't have access to every router a laptop uses.
I want the code to be permanently compatible.
Use DynDNS.com or NoIP.com portal. You install program on laptop which check your IP frequencly and sends current IP to portal which assigns this IP to your address like "my_laptop.noip.com". Then people can access your laptop using "my_laptop.noip.com" instead of IP address.
You always assign socket to IP of local network card (NIC) like WiFi. You can't assing to external IP. You have to config your router so requests to external IP:port will be send to your local IP:port. Of course Internet Provider routers can block your ports and it will not work.

Python Sockets: Connection Timeout

I'm trying to write two short python scripts that will connect two or more machines to each other, one as the server and the others as clients. It worked perfectly when testing the client and the server script on the same computer, but when I tried it from another computer the client kept timing out; it couldn't connect to the server. Here's my server code:
import socket
server = socket.socket()
host = "computername"
port = 12345
server.bind((host, port))
server.listen(5)
client, addr = server.accept()
Client code:
import socket
server = socket.socket()
host = "computername"
port = 12345
server.connect((host, port))
Any clue as to why the machines can't connect?
I think, you are changing host variable properly when running both client and server scripts in different machines. Try by changing that properly/or using IP address of server machine.
The communication could be prohibited by a firewall.
To rule out DNS related problem, try IPs instead of hostnames:
# server: listen on all interfaces
server.bind(('', port))
and:
# client: specify server's IP address
server.connect(("192.168.XX.YY", port))
with a real IP address, of course.

Categories