TimeoutError python socket - python

I would like to make a BT communication between a laptop with a dongle BT and a Raspberry. They are both connected on a PAN network so they have both one IP address.
For the communication, I use a TCP socket. On the server part, I can create my socket until the accept method. Then I go on my RPi 3 and I run my python script:
import socket
hote = "192.168.50.1"
port = 1000
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((hote, port))
print("Connection on {}".format(port))
socket.close()
But I always have this output after few minutes:
Traceback (most recent call last):
File "socketClient.py", line 7, in <module>
socket.connect((hote, port))
TimeoutError: [Errno 110] Connection timed out
I don't know why... Do you have an idea ? I've tried the command telnet addr_ip port on my laptop and i success the connection with the server.

It was a firewall problem because he stopped the entrance connection.I realized there when I reversed the roles. I put the server code on RPI and client code on my laptop and it worked.

First of all, did you bind the socket? Second, are you listening on that IP and port?
The normal approach creating socket connections is:
Server side:
Create a socket
Bind the socket to a specyfic interface and port
Let the socket listen.
in a loop, try to accept connections to the socket
handle the connection
Client side:
Create a client_socket
Try to connect to the server socket.
Some information about network-programming in python:
here and here

Related

Python socket connection not working over Local Network

I'm trying to get two computers (my PC and my laptop) to communicate over the Local Network using the Socket module in python.
This is the Server side code running on my PC (connected via LAN):
import socket
HOST = '192.168.1.3' #local PC IP
print(HOST)
PORT = 8080 # 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)
if not data:
break
conn.sendall(data)
And this is the Client side code, running on my Laptop (connected over WiFi):
import socket
TCP_IP = '192.168.1.3'
TCP_PORT = 8080
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print("received data:", data)
The thing is: when I execute both codes, the Server side stays idle waiting for a connection and the Client side, after a while stops and returns the following timeout error:
Traceback (most recent call last):
File "C:\Users\...\client.py", line 13, in <module>
s.connect((TCP_IP, TCP_PORT))
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
I can't understand why it won't connect from another device in the same network while it works perfectly if I execute the Client code on the same machine as the Server, even if when I run netstat -an in the CMD I can see the computer listening on that port:
TCP 192.168.1.3:8080 0.0.0.0:0 LISTENING
I tough it had something to do with the port forwarding so I tried playing around with it but I'm having troubles with that too (the ports seem to remain closed).
I really don't know what to do next, if you have some advice or know something else I could try please reply.
It actually was a firewall problem, I just needed to disable the windows defender firewall for the local network and now everything is working fine
In Windows 10, I had to open the port I was using for the socket, and it worked for me.
Here is a link to the instructions.
You're listening and connecting to the same IP - you need to listen to the client's IP(or just any IP with the correct port number) on the server and connect to the server's IP on the client.
For example, if the client's IP is 1.2.3.4 and the server's is 1.2.3.5, then
# server side
s.bind(('1.2.3.4', 8080)) # CLIENT_IP = '1.2.3.4'; PORT = 8080
# can also be s.bind(('0.0.0.0', 8080)) if you want multiple clients to connect.
# client side
s.connect(('1.2.3.5', 8080)) # SERVER_IP = '1.2.3.5'; PORT = 8080

Python 3 localhost connection

I'm trying to run the below program but I keep getting connection error's:
from socket import *
from codecs import decode
HOST = 'localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST, PORT)
server = socket(AF_INET, SOCK_STREAM)
server.connect(ADDRESS)
dayAndTime = decode(server.recv(BUFSIZE), 'ascii')
print(dayAndTime)
server.close()
ERROR: ConnectionRefusedError: [Errno 61] Connection refused
Any idea what's going on?
If your book doesn't mention the other half of sockets, you need a better book.
Socket basics are easy. You have one process listen on a port, waiting for connections. Commonly we'll call this a 'server'. Another process (perhaps on the same machine, perhaps remote) attempts to connect to that port. We'll call that the client.
If no one is listening, then when the client attempts to connect they'll get your error Connection Refused.
So, set up a listening process. Below, on the left is server code; on the right is client code. Top-to-bottom is the "flow".
server = socket(AF_INET, SOCK_STREAM) # <- just like your example
server.bind(ADDRESS) # rather than 'connect', we 'bind' to the port
server.listen(1) # bind "claims" the port, so next we call listen & wait...
# Meanwhile...
# Your client process
client = socket(AF_INET, SOCK_STREAM)
client.connect(ADDRESS)
# It's only at this moment that the client reaches across the network to the server...
# On connect, the listening server wakes up, and needs to "accept" the connection
(s, remote_addr) = server.accept()
Once accepted, you can now send/recv on the s socket on the server-side, and send/recv from the client socket on the client side. Note that the server variable is not the socket to communicate on -- it's used to listen for new connections. Instead, you read/write on the socket object returned as first item of accept().
There's lots more to consider but this is at the heart of the Internet and has been pretty much unchanged since the 1980s.
Image from wikipedia entry for Berkeley Sockets:

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?

Connecting to a simple sockets python server remotely

I am trying to setup a very simply sockets app. My server code is:
import socket
s = socket.socket()
host = socket.gethostname()
port = 1234
s.bind((host,port))
s.listen(5) #Here we wait for a client connection
while True:
c, addr = s.accept()
print "Got a connection from: ", addr
c.send("Thanks for connecting")
c.close()
I placed this file on my remote Linode server and run it using python server.py. I have checked that the port is open using nap:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
1234/tcp open hotline
I now run the client.py on my local machine:
import socket # Import socket module
s = socket.socket() # Create a socket object
port = 1234 # Reserve a port for your service.
s.connect(("139.xxx.xx.xx", port))
print s.recv(1024)
s.close # Close the socket when done
However I am not getting any kind of activity or report of connection. Could someone give me some pointers to what I might have to do? Do I need to include the hostname in the IP address I specify in the client.py? Any help would be really appreciated!
I've just summarize our comments, so your problem is this:
When you trying to using the client program connect to the server via the Internet, not LAN.
You should configure the
port mapping on your router.
And however, you just need configure the
port mapping for your server machine.
After you did that, then you can use the client program connect to your server prigram.

Selecting random port on a remote host

I want to select a random high port on a remote linux machine and use it for my application. On my localhost, I can bind to port 0 and get a random high port, but this does not work if I give a remote host.
The code is as follows:
host = "remote_host"
def get_open_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
Error:
Traceback (most recent call last):
File "server.py", line 25, in <module>
port = get_open_port()
File "server.py", line 11, in get_open_port
s.bind((host,0))
File "<string>", line 1, in bind
Well I guess you are bit confused with the client-server communication. Before getting to the solution of your problem lets first revisit the client-server communication process. Normally it is the client who makes/initiates the connection request (simply a connection) to the server. The client makes a request to the server on a remote port which is listening for incoming connections. This remote port should be open on the server side and should be waiting for incoming connections. For eg: If you want to connect to a remote server on the remote port number 15200, then it is mandatory that you should open the port number 15200 on the server side and it should be listening for any incoming connections/requests. Also, the client will know this in advance to which remote port it should make a request for a connection!
Lets understand some more facts before getting to the one of the possible solution to your problem. First lets understand the server side.
Server side: You are trying the server to use any random port for accepting incoming connections from a client. It will surely work as you are binding port number 0 in your server code as s.bind((host,0)). When you bind the port number 0 then your server (actually the OS which is running the server script) will use any random high port number for accepting the remote connections which will be usually greater than 1023. You can test this by following code snippet. Run the following code snippet and you may notice that the server is opening random high port numbers.
import socket
host = "127.0.0.1"
def get_open_port():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
for i in range(0,5):
print "Opening port no. %s"%get_open_port()
On executing the above code you'll shall see that a random port number is being selected by the server code to accept incoming connections every time. But it is also closing it after wards using s.close(). In my case the output was as below (You may get a different set of port numbers):
Opening port no. 60876
Opening port no. 60877
Opening port no. 60878
Opening port no. 60879
Opening port no. 60880
So, I guess now you understood the server part. Lets discuss the client side now.
Client side: As mentioned earlier that a client needs to know the remote server port to which it needs to connect. A typical client code looks as given below:
import socket
host = "127.0.0.1"
port = 60880
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
In the above code snippet this line s.connect((host, port)) you need to mention the host the remote host name or IP and port the remote port to which you want to connect to.
So it means that client should know the port number in advance! As a result you have to mention the port in your client code. As I have done in my code snippet as port = 60880.
Now coming to your question: As you already noticed from above text that you have to mention the remote server's port number in client code to make a request for a connection. So, you can't expect your client to figure out itself the remote port of the server which is actually listening for incoming request. The client code can't do this by its own.
Solution:
So what if the client code can't figure out by itself the remote port number we'll make it to figure it out! ;) What we know is if you bind the port number 0 on server side then a random port number will be selected which will be greater than 1023. So, it means the random port number will always be greater than 1023. Also, the maximum value of port number is 65535. Ultimately we come to a conclusion that the random port that will used by the server will be any port number in this range 1024 - 65335.
Now all you have to do is in your client code you have to use a range of port numbers to which it should make connection. Because we don't know what remote port is listening on the server side for accepting incoming requests/connection!
Sample code for plying around: I tested these code snippets using my localhost. Here is the server code. Run the server code first then run the client code. Upon executing the server code, it'll display in console/output that what is the random port number opened for accepting incoming request/connections. When a client is connected the server will display a message the Got a client connected along with the IP of the client.
#This is the server script
import socket
host = "127.0.0.1"
def get_open_port():
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mySocket.bind((host,0))
mySocket.listen(1)
port = mySocket.getsockname()[1]
print "Port opened for incoming connections %d"%port
(clientSocket, clientAddress) = mySocket.accept()
print "Got a client: ", clientAddress
clientSocket.close()
mySocket.close()
get_open_port()
Here is a client code sample that will do this crazy stuff. It will try to connect on all the ports from 1024 - 65335 and when it finds any remote port which is listening for incoming connections. It will display a message "Connected to remote port" and then close the socket and continue looking for more open ports until it reaches the last port number 65355.
#This is the client script
import socket
host = "127.0.0.1"
def startConn():
for port in range(1024,65336):
try:
myClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Trying remote port: ",port
myClientSocket.connect((host,port))
print "Connected to remote port: ",port
myClientSocket.close()
except socket.error as msg:
myClientSocket.close()
continue
startConn()
This is just a sample code, I am intentionally closing the sockets after a successful is established. You can do something else what you ever you prefer. I hope now it is quite clear to you regarding server-client communication.

Categories

Resources