Python websockets server works on localhost but not on server - python

I made a basic chat client and server using python websockets, ran it on my pc and it worked completely fine, when I uploaded it to my windows server machine (which has the port '12345' forwarded) and tried to access it using a client from my pc I got a ConnectionRefusedError
I've tried switching to a different port (which was also forwarded) but it didn't change the result
The client (this is the bit that caused the error)
ip = input("IP Address: ")
port = int(input("Port: "))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
The server
def open_socket(PORT:int, MAX_USERS:int):
new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ("localhost", PORT)
new_socket.bind(server_address)
new_socket.listen(MAX_USERS)
return new_socket
Here's the error:
Traceback (most recent call last):
File "client.py", line 24, in <module>
sock.connect((ip, port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
EDIT: After trying out Jin's answer I'm now getting a timeout error at the same place (line 24 in client.py)
EDIT #2: It is now working! I changed the port to the original one (12345) and I successfully connected to the server!

Even though you changed a port forward config in your router, you still need to check whether your server is accepting incoming traffic in the firewall setting. You can do this from Control Panel-Security or Windows Firewall (Sorry I don't remember the exact name of the menu of the Windows).
You should bind your IP with the socket, not localhost. You would want to programmatically get your IP address, rather than using hard-coded one. The followed link would help.
Finding local IP addresses using Python's stdlib

Related

Win Error 10061 No connection could be made because the target machine actively refused it

I have been experimenting with the socket library for python. I made a simple program for the server and client where the client can message the server.
Here is my code for the server:
import socket
print("Host")
socket_main = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_main.bind(('127.0.0.1', 9999))
socket_main.listen(1)
conn, addr = socket_main.accept()
while True:
data = conn.recv(1204).decode()
print(data)
conn.close()
Here is my code for the client
import socket
print("Client")
socket_main = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_main.connect(('127.0.0.1', 9999))
while True:
message = input(": ")
socket_main.send(message.encode())
socket_main.close()
When I run these programs in two different terminals on one computer it works just fine, but when I try to run the server and client on different computers I get an error on the clients end saying, "No connection could be made because the target machine actively refused it".
I have tried changing the port multiple times but it didn't help. I have looked through a lot of other forums and I haven't been able to fix this problem for a while now so I decided to ask here.
when I try to run the server and client on different computers I get an error on the clients end
That is because you are using127.0.0.1 on both sides. That is the localhost loopback IP address. It works when the client and server are on the same machine, but it is not routable on the LAN network.
You need to:
change the server to listen on either 0.0.0.0 (to listen on all installed network interfaces), or its actual LAN IP address (just the network interface attached to the LAN).
change the client to connect to the server's hostname or IP address on the LAN.
I have tried changing the port multiple times but it didn't help
The problem is nit with the port, but with the IP address.

Firewall is not allowing my python client application to connect to a server running on my machine even after I turn off firewall completely

I am learning about the python socket library and am running into problems whenever I try to connect to the server running on my localhost with a client application.
Here is the server code:
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
print(data)
Here is the code for my client application:
import socket
HOST = "localhost" # The server's hostname or IP address
PORT = 65432 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
Here is my error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
Here is what I have tried so far:
Disabling my Window's 10 firewall completely on the windows command prompt with the use of the following command:
netsh advfirewall set allprofiles state off. This did not work
To windows firewall I added an inward rule and outward rule that allows any application on my OS to access a service running on port 65432
I changed my python version from 3.8.2 to 3.7.7 because before hand I was able to run this code perfectly and I was using a python 3.7 version
I tried multiple different methods of setting the HOST variable, which include "localhost", '127.0.0.1', socket.gethost(), and socket.gethostbyname("localhost")
I am able to connect to the server through the use of the Window's telnet application but that is it. To be honest I have exhausted possible solutions that I can find online, and I know that this question has came up on this website a lot, but I have honestly tried every solution I have seen so far - which included three hours of searching.
I appreciate any possible help that you guys can give, thanks.
Since the code was working earlier in the machine,this doesn't seem to be code issue.
Also the code ran fine in my machine.
I suggest you to run through the below steps once again:
Solution 1:
1. edit the server address as 127.0.0.1 or the host private IP in both the code just to be assured there is no discrepancy.
2. Start the server program first and make sure it didn't terminate.
3. Start the client application and check if the server program threw any error or exceptions.
Solution 2:
Change the port number and follow solution 1.
Solution 3:
Switch off the windows firewall from the UI just to be sure.
Follow the solution 1 steps
Solution 4:
Change the server address as host=''

How to connect a socket to another computer's socket through Internet

I recently have some difficulties to connect a socket to another computer's socket through Internet, an image is worth a thousand words:
Computer A is running this "listener.py" script:
import socket
PORT = 50007
BUFFER = 2048
HOST = ''
if __name__ == '__main__':
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(BUFFER)
if not data: break
conn.sendall(data)
Computer B is running this "sender.py" script:
import socket
HOST = '101.81.83.169' # The remote host
PORT = 50007 # The same port as used by the server
if __name__ == '__main__':
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
So first of all, I run the "listener" script of the computer A. Then, I run the "sender" script of the computer B. However, when I execute the "sender" script, I received a error message which explains me that I am not authorized to connect to this remote address.
So I would like to know how can I connect a socket to another socket through internet without changing the router configurations.
Thank you very much for your help.
Edit: Here the error message (I didn't execute the same script for some reasons, but it's the same error message)
sock.connect(('101.81.83.169',50007)) Traceback (most recent call last): File "<stdin>", line 1, in
<module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in
meth return getattr(self._sock,name)(*args) socket.error: [Errno 61] Connection refused
So I would like to know how can I connect a socket to another socket through internet without changing the router configurations.
You can't. The public IP address belongs to your router. Your server isn't listening in the router, it is listening in some host behind the router. You have to open that port in your router and forward it to the host your listener is running in: whatever that means in your particular router. Otherwise the router will refuse the connection, as it doesn't have anything listening at that port.
Computer B can't directly connect to computer A since it has an IP address which is not reachable from the outside. You need to set up a port forwarding rule in the 101.81.83.169 router that redirects incoming connection requests for port 50007 to IP address 192.168.0.4.
However, since you say that you are seeking a solution without changing router configurations, you need something different.
In this case, you could setup an intermediate server running on the public Internet that both computers can then connect to and serves as an intermediate tunneling platform between them. Solutions for this already exist, for example have a look at ngrok, which has Python bindings available.
From the book "Computer Networking: A Top-Down Approach", there is a part which is very interesting on page 149 about how Bittorents work:
Each torrent has an infrastructure node called a tracker. When a peer joins a torrent, it registers itself with the tracker and periodically informs the tracker that it is still in the torrent. In this manner, the tracker keeps track of the peers that are participating in the torrent. A given torrent may have fewer than ten or more than a thousand peers participating at any instant of time. Alice, joins the torrent, the tracker randomly selects a subset of peers (for concreteness, say 50) from the set of participating peers, and sends the IP addresses of these 50 peers to Alice. Possessing this list of peers, Alice attempts to establish concurrent TCP connections with all the peers on this list. Let’s call all the peers with which Alice succeeds in establishing a TCP connection “neighboring peers.
So:
- Step 1: Alice connects to the tracker, the tracker gives to Alice the ip addresses of Bob and Mick.
- Step 2:Alice receives the ip addresses of Bob and Mick, then she can try to establish TCP/IP connections for downloading the file.
I don't remember having to set up any router configuration when I wanted to download files from Bittorent.
So what am I missing?

Python socket error: Can't convert 'tuple' object to str implicitly

I start to build a simple client - server chat room today and I am new to Python and network connection. I made a simple code on server something like this:
HOST = socket.gethostname()
PORT = 21238
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
On the client:
HOST = socket.gethostbyaddr('54.201.33.XX') #54.201.33.XX is my EC2 public IP
PORT = 21237
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
I have already running my server code on server and when I am trying to run client code on my PC. I got the error:
Traceback (most recent call last):
s.connect((HOST, PORT))
TypeError: Can't convert 'tuple' object to str implicitly
I have found some sample codes but nealy all of them are using local host. Thank you for your helps.
/////
Based on #Jon S.'s answer. My client code should be
HOST = '54.201.33.XX'
But still time out to connect to server. I am sure my ip is correct.
The problem is
HOST = socket.gethostbyaddr('54.201.33.XX')
in your second example. gethostbyaddr returns a tuple, containing (hostname, a list of aliases, ip addresses). connect expects a string as the first element of the tuple that specifies the address and port to connect to.
You can change this to
HOST = '54.201.33.XX'
and it should work.
I found the answer.
On server, the HOST = socket.gethostname(); On client, the HOST = '54.201.33.XX', which is your server ip address
In EC2, the default security setting is only open ssh. You should open the Port you have used in your codes. The operations are following:
2.1 Enter AWS console and enter EC2
2.2 Find Security Group on the left under NETWORK & SECURITY
2.3 Click your current security group (For me, it is not the default one) and open Inbound on the below information
2.4 Choose Custom TCP rule and enter your Port range (21237 in my pasted code) and click on add Rules
2.5 DO NOT forget to press button "Apply Rule Changes"!!!

Why am I getting the error "connection refused" in Python? (Sockets)

I'm new to Sockets, please excuse my complete lack of understanding.
I have a server script(server.py):
#!/usr/bin/python
import socket #import the socket module
s = socket.socket() #Create a socket object
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
s.listen(5) #Wait for the client connection
while True:
c,addr = s.accept() #Establish a connection with the client
print "Got connection from", addr
c.send("Thank you for connecting!")
c.close()
and client script (client.py):
#!/usr/bin/python
import socket #import socket module
s = socket.socket() #create a socket object
host = '192.168.1.94' #Host i.p
port = 12397 #Reserve a port for your service
s.connect((host,port))
print s.recv(1024)
s.close
I go to my desktop terminal and start the script by typing:
python server.py
after which, I go to my laptop terminal and start the client script:
python client.py
but I get the following error:
File "client.py", line 9, in
s.connect((host,port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
I've tried using different port numbers to no avail. However, I was able to get the host name using the same ip and the gethostname() method in the client script and I can ping the desktop (server).
Instead of
host = socket.gethostname() #Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) #Bind to the port
you should try
port = 12397 # Reserve a port for your service
s.bind(('', port)) #Bind to the port
so that the listening socket isn't too restricted. Maybe otherwise the listening only occurs on one interface which, in turn, isn't related with the local network.
One example could be that it only listens to 127.0.0.1, which makes connecting from a different host impossible.
This error means that for whatever reason the client cannot connect to the port on the computer running server script. This can be caused by few things, like lack of routing to the destination, but since you can ping the server, it should not be the case. The other reason might be that you have a firewall somewhere between your client and the server - it could be on server itself or on the client. Given your network addressing, I assume both server and client are on the same LAN, so there shouldn't be any router/firewall involved that could block the traffic. In this case, I'd try the following:
check if you really have that port listening on the server (this should tell you if your code does what you think it should): based on your OS, but on linux you could do something like netstat -ntulp
check from the server, if you're accepting the connections to the server: again based on your OS, but telnet LISTENING_IP LISTENING_PORT should do the job
check if you can access the port of the server from the client, but not using the code: just us the telnet (or appropriate command for your OS) from the client
and then let us know the findings.
Assume s = socket.socket()
The server can be bound by following methods:
Method 1:
host = socket.gethostname()
s.bind((host, port))
Method 2:
host = socket.gethostbyname("localhost") #Note the extra letters "by"
s.bind((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48")
s.bind((host, port))
If you do not exactly use same method on the client side, you will get the error: socket.error errno 111 connection refused.
So, you have to use on the client side exactly same method to get the host, as you do on the server. For example, in case of client, you will correspondingly use following methods:
Method 1:
host = socket.gethostname()
s.connect((host, port))
Method 2:
host = socket.gethostbyname("localhost") # Get local machine name
s.connect((host, port))
Method 3:
host = socket.gethostbyname("192.168.1.48") # Get local machine name
s.connect((host, port))
Hope that resolves the problem.
host = socket.gethostname() # Get the local machine name
port = 12397 # Reserve a port for your service
s.bind((host,port)) # Bind to the port
I think this error may related to the DNS resolution.
This sentence host = socket.gethostname() get the host name, but if the operating system can not resolve the host name to local address, you would get the error.
Linux operating system can modify the /etc/hosts file, add one line in it. It looks like below( 'hostname' is which socket.gethostname() got).
127.0.0.1 hostname
in your server.py file make : host ='192.168.1.94' instead of host = socket.gethostname()
Pay attention to change the port number. Sometimes, you need just to change the port number. I experienced that when i made changes over changes over syntax and functions.
I was being able to ping my connection but was STILL getting the 'connection refused' error. Turns out I was pinging myself! That's what the problem was.
I was getting the same problem in my code, and after thow days of search i finally found the solution, and the problem is the function socket.gethostbyname(socket.gethostname) doesnt work in linux so instead of that you have to use socket.gethostbyname('put the hostname manually') not socket.gethostbyname('localhost'), use socket.gethostbyname('host') looking with ifconfig.
try this command in terminal:
sudo ufw enable
ufw allow 12397

Categories

Resources