I am trying to set up a Python socket between my Raspberry Pi (running Raspbian) and my Macbook Pro (running Mavericks).
Both devices are connected to the same WiFi network in my appt. I run the server code on my RPi and then the client code on my Macbook (I have also tried the reverse). I think that I am missing a set up step because the code I am using I found on multiple sites, so I assume it works. I also checked that my Macbook has firewall turned off.
Server Code:
from socket import *
host = "127.0.0.1"
print host
port = 7777
s = socket(AF_INET, SOCK_STREAM)
print "Socket Made"
s.bind((host,port))
print "Socket Bound"
s.listen(5)
print "Listening for connections..."
q,addr = s.accept()
data = raw_input("Enter data to be sent: ")
q.send(data)
Client Code:
from socket import *
host = "127.0.0.1"
print host
port=4446
s=socket(AF_INET, SOCK_STREAM)
print "socket made"
s.connect((host,port))
print "socket connected!!!"
msg=s.recv(1024)
print "Message from server : " + msg
I get the error:
Traceback (most recent call last):
File "TCPclient.py", line 9, in <module>
s.connect((host,port))
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
My process for executing the code is:
type "python TCPserver.py" into RPi terminal
type "python TCPclient.py into Macbook terminal
Then I receive the error message on my Macbook, no error on the RPi
My questions are:
Is 127.0.0.1 the proper input for "host"? (please note I also tried "localhost")
Does the input for host have to be the same for the client and server code?
Should the RPi and Macbook both be connected to the same WiFi network?
Is there any set up that needs to be done on either the RPi or my Macbook in order for this to work (Please note my RPi is Model B, new, and I did not set up anything else on it before this)
Do you know why I am receiving this error and how to fix it?
Your help is greatly appreciated!!
127.0.0.1 is a special IP address for local machine.
You must set the real IP address (on your LAN) of you mac in the client code.
You should also bind on this IP on the server, or on 0.0.0.0 to bind on all available IP addresses.
You must also use the same port number on both client and server.
And to reply to your questions:
Is 127.0.0.1 the proper input for "host"? (please note I also tried "localhost")
127.0.0.1 is the same than localhost, it means the local machine. This will work if you run the client and the server on the same machine, else you need the real IP address of your mac. Try ifconfig in a console.
Does the input for host have to be the same for the client and server code?
Yes and no. On the server you bind to a port and an address, so you'll wait for connections on this port and address. You can use the IP address, or 0.0.0.0.
Should the RPi and Macbook both be connected to the same WiFi network?
Yes and no. It will work with the same WiFi network, but it will also work with two different WiFi networks if they are connected together directly or with a IP router. Most of the time though they are connected to the internet through a NAT (network address translator), and then it will not work.
Is there any set up that needs to be done on either the RPi or my Macbook in order for this to work (Please note my RPi is Model B, new, and I did not set up anything else on it before this)
I don't know much about the RPi but it looks like standard TCP sockets, that should work out of the box.
Do you know why I am receiving this error and how to fix it?
As I stated at the beginning: You try to connect to the RPi (127.0.0.1) on the wrong port.
You have created a listener on port 7777, then you connected on 4446 !!!!!
just connect on the same port you are listening to =)
Related
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)
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.
[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.
I have 2 computers on the same LAN. The first PC has an ip address 192.168.178.30, the other PC has an ip address 192.168.178.26.
Ping, traceroute, telnet, ssh, everything works between the two PCs. Both PCs run the same OS - CentOS 7 and both PCs have the same python version 2.7.5 (checked with the python -V command).
I copied simple python code from a computer networking book.
client.py
from socket import *
serverName = '192.168.178.30'
serverPort = 12000
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
sentence = raw_input('Input lowercase sentence: ')
clientSocket.send(sentence)
modifiedSentence = clientSocket.recv(1024)
print 'From Server:', modifiedSentence
clientSocket.close()
server.py
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('192.168.178.30',serverPort))
serverSocket.listen(5)
print 'The server is ready to receive'
while 1:
connectionSocket, addr = serverSocket.accept()
sentence = connectionSocket.recv(1024)
capitalizedSentence = sentence.upper()
connectionSocket.send(capitalizedSentence)
connectionSocket.close()
The code works when it is ran on the same PC (where the server is listening on localhost).
When I run the client code on one PC and the server code on the other PC I get this error on the client side.
Traceback (most recent call last):
File "client.py", line 5, in <module>
clientSocket.connect((serverName,serverPort))
File "/usr/lib64/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 113] No route to host
Can someone help?
Check the firewall (on the server).
I stopped the firewall like Messa suggested and now it works.
service firewalld stop
I still don't understand what the problem was. I even tried using different distributions. Do all distributions have strict firewalls or something. For example Ubuntu to Ubuntu, Ubuntu to CentOS, CentOS to Ubuntu I still had the same problem (error).
~]#supervisord
Error: No config file found at default paths (/usr/etc/supervisord.conf, /usr/supervisord.conf, supervisord.conf, etc/supervisord.conf, /etc/supervisord.conf); use the -c option to specify a config file at a different path
For help, use /usr/bin/supervisord -h
You should use
ln -s /etc/supervisor/supervisord.conf /usr/etc/supervisord.conf
None of this stuff worked for me. I just connected both the devices to the same WiFi network and my program worked!
You can also get this same error ([Errno 113] No route to host) if you are trying to connect 2 devices on the same network. the error can be fixed by double checking to make sure both devices are connected to the mqtt_client or whatever you are using. as soon as I connected the device I was trying to talk to everything worked as to be expected.I would also check to make sure the right IP_Address is being passed
We had this problem. I am putting our findings here in case anyone else stumbles across this question like I did.
Our configuration:
Host A: IP address 192.168.0.1, netmask 255.255.255.0
Host B: IP address 192.168.1.1, netmask 255.255.254.0
Neither host has a default gateway.
We are connecting from Host B to Host A. (That is not a typo.) The connect call succeeds, but when we try to send data, we get errno 113 aka. EHOSTUNREACH aka. "No route to host".
The fix, of course, was to change the subnet on Host A to match Host B.
We were surprised to see this error on a connection within the same subnet / same LAN. And we were surprised that connect succeeded followed by send failing. And we were surprised to see this error on Host B even though the network configuration on Host B itself was fine.
Somehow, the incorrect subnet on Host A caused this error on Host B...
...and just like that, today I learned about ICMP "destination unreachable" messages.
So you have a basic understanding of the parts im using, I have:
Arduino Uno
Seeed Studio GPRS Shield v2.0 (http://www.seeedstudio.com/wiki/GPRS_Shield_V2.0)
Ultimate GPS for Adafruit V3.3 (https://www.adafruit.com/products/746?gclid=Cj0KEQjw3-W5BRCymr_7r7SFt8cBEiQAsLtM8qn4SCfVWIvAwW-x9Mu-FLeB6hLmVd0PAPVU8IAXXPgaAtaC8P8HAQ)
Here is my problem:
I have tested the Arduino stacked with the GPRS shield, and it works fine with regards to accessing the internet through TCP, sending SMS, etc.. However, my application requires me to send GPS data from the adafruit GPS to a web server that I have already coded with Django and postgresql. The backend is set up.
I need to send the data from the Uno (client) to my laptop (server), which I coded in python (This is just to check whether it is creating a connection):
#!/usr/bin/env python
import socket
# import postgres database functions
TCP_IP = '192.168.1.112'
TCP_PORT = 10000
BUFFER_SIZE = 40
server_address = (TCP_IP,TCP_PORT)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created.'
# Bind socket to TCP server and port
try:
s.bind(server_address)
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket Bind Complete.'
# Start Listening on socket
s.listen(1) # Puts socket into server mode
print 'Listening on port: ', TCP_PORT
# Now Keep Talking with the client
while (1):
# Wait to accept a connection
conn, addr = s.accept() # Wait for incoming connection with accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if not data: break
print "recieved data: data", data
conn.send(data) #echo
conn.close()
I dont think there is a problem with this. From this I will post data to my postgreSQL database. However, When I try to use AT commands on the SIM900 module to connect to the server using port 10000, I cannot connect:
AT+CIPSHUT
SHUT OK
AT+CGATT?
+CGATT: 1
OK
AT+CIPMUX=0
OK
AT+CSTT="fast.t-mobile.com","",""
OK
AT+CIICR
OK
AT+CIFSR
6.60.94.49
AT+CIPSTART="TCP","192.168.1.112,"10000"
OK
STATE: TCP CLOSED
CONNECT FAIL
I have tried connecting through TCP and replaced the AT+CIPSTART line with the below statement and it worked, so I know TCP works:
AT+CIPSTART="TCP","www.vishnusharma.com", "80"
Is the IP i'm using wrong? I'm new to this, but if it makes a difference, im using Ubuntu 16.04 partitioned on my Mac OSX. I have also checked the APN for T-mobile and it seems fine.
Any help would be greatly appreciated. Thank You!
The IP you're using is inside a NAT since it starts with 192.168. Unless you have a private apn with the mobile operator you're using, you won't be able to reach your Ubuntu from a public IP. Your ISP gives you a public IP address which ir administrated by your router, so if you want this to work, you'll have to do a port forwarding from your router to your Ubuntu.
To do the port forwarding you have to get in the router's configuration page (Typically 192.168.1.1 but depends on the model) an there you'll have to redirect the port XXX to 192.168.1.112:10000. After that you have to obtain your public IP (curl ifconfig.co) and use it to access from the SIM900.
First of all as a suggestion, you can combine the two shields by using SIM908 (unless you are getting more precision on your GPS shield). Since your TCP connection is working, I bet that the port 10000 on your ubuntu is blocked by the firewall. You can first try to turn off your firewall and see if it works. If it did not worked its something else. If it worked, turn on your firewall and then unblock the tcp port using the following command:
sudo ufw allow 10000/tcp