I am trying to build a simple Bluetooth client / server where my Raspberry Pi is the server and my laptop the client.
This is the server code (running on my Raspberry Pi):
#!/usr/bin/python
# -*- coding: utf-8
import wifi, bluetooth
uuid="1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
print "Setting up Bluetooth socket"
try:
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.bind(("", 0))
sock.listen(1)
except IOError as e:
print str(e)
print "Registering service"
try:
bluetooth.advertise_service(sock, "MyService", uuid)
while True:
print "Waiting for connection..."
client_sock,address = sock.accept()
print "Accepted connection from {0}".format(address)
data = client_sock.recv(1024)
print "Received data: {0}".format(data)
print "Closing client socket."
client_sock.close()
except IOError as e:
print str(e)
This seems to work, the script runs and blocks with Waiting for connection....
Then, my client code:
#!/usr/bin/python
# -*- coding: utf-8
import bluetooth, time
mac = "00:15:83:E5:E2:46"
uuid = "1e0ca4ea-299d-4335-93eb-27fcfe7fa848"
service = []
retry = 1
while len(service) == 0:
print "Looking for service on {0}, try {1}".format(mac, retry)
service = bluetooth.find_service(address=mac, uuid=uuid)
retry = retry + 1
time.sleep(1)
if len(service) == 1:
service = service[0]
print "Service found. Name={0}".format(service["name"])
print "Connecting to service."
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
try:
sock.connect((mac, service["port"]))
print "Connected to service on {0} on port {1}".format(mac, service["port"])
except bluetooth.btcommon.BluetoothError as e:
print "Connection failed: {0}".format(e)
elif len(service) == 0:
print "No service found on mac {0}.".format(mac)
else:
print "{0} services found for mac/uuid, ignored.".format(len(service))
Also works, up until I try to connect() to the Raspberry Pi. I get the following error:
Connecting to service.
Connection failed: (111, 'Connection refused')
I tried connecting the laptop to the Raspberry Pi (it finds it and says it is "Connected") and searching for more info online, but wasn't able to find anything.
This error occures when u want to connect to not listening port.
U are listening on port "0" .....
Change it to for example 9999 and then client has to connect to that port on the server adress
Related
I have written a client-server python program where the client can send the data to the server. But when the client is trying to connect with the server I am getting the following error.
[Errno 110] Connection timed out
Sending Key to Server
Traceback (most recent call last):
File "client.py", line 43, in <module>
s.send(str(id))
socket.error: [Errno 32] Broken pipe
I tried the following solutions
Broken Pipe error and How to prevent Broken pipe error but none of them solved the issue.
Here are my client and server code
client.py
import socket
import os
import subprocess
from optparse import OptionParser
from random import randint
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Socket has been successfully created"
except socket.error as err:
print "socket creation failed with error %s" %(err)
# The Manager Address and port
host_ip='192.168.43.123'
port =10106
# Generates a random number say xxxx then its client id becomes 'clxxxx' and home directory made at the server as '/home/clxxxx' with permissions 700
def random_with_N_digits(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
id=random_with_N_digits(4)
id="cl"+ str(id)
# Looks for a public key in .ssh folder if temp.pub not present. If not found generates a ssh public private key and sends it to manager which then copies it to the server
subprocess.call(["bash","keygen.sh"])
#s = socket.socket()
try:
s.connect((host_ip,port))
print "the socket has successfully connected to Backup Server IP == %s" %(host_ip)
except socket.error as err:
print err
f = open('temp.pub','r')
print "Sending Key to Server"
j = "-"
s.send(str(id))
l=f.read(8192)
while(l):
print 'Sending...'
s.send(l)
l = f.read(8192)
try:
client_id=s.recv(1024)
data=s.recv(12)
ip=s.recv(24)
print client_id,
print data, ip
except:
print "An Unknown Error Occurred!"
f.close()
# Writes the parameters of client in the file 'backup_dir.txt'
with open('backup_dir.txt','w') as the_file:
the_file.write(client_id)
the_file.write('\n')
the_file.write(data)
the_file.write('\n')
the_file.write(ip)
the_file.write('\n')
f.close()
s.close()
server.py
import socket
import subprocess
import os
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Socket has been successfully created"
except socket.error as err:
print "socket creation failed with error %s" %(err)
port = 10106
s.bind(('', port))
print("socket binded to %s port" %port)
s.listen(10)
print("socket is listening")
while(True):
print("waiting for a connection")
c, addr = s.accept()
print("Got a connection from", addr,c)
clientID =(c.recv(8192))
key =(c.recv(8192))
print clientID
print key
with open("temp.pub", 'w') as fp:
fp.write(key)
note=subprocess.check_output("./test_user.sh "+ clientID, shell=True)
note = str(note)
print(len(note))
flag, path, serverIP = note.split(":")
print(flag)
print(path)
print(serverIP)
if flag:
c.send(clientID)
c.send(path)
c.send(serverIP)
os.remove("temp.pub")
else:
c.send("Unable to add Client.")
How do I fix this problem so that the client can send the data to the server without any error?
Thank You in advance.
The error resolved.
It was due to the firewall issue as #RaymondNijland was mentioning, Thanks.
I added the rule in the firewall to allow the following port for Socket Connection and it worked.
sudo ufw allow 10106
I have 3 devices -> 2*PC and 1 Raspberry Pi. 2 PCs are only for the sake of testing. 2PC = 2 Laptops with Windows 10.
On raspberry pi I have Bluetooth service(Py 2.7 but 3.5 should also work if print()):
import bluetooth
try:
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
server_sock.bind(("",0))
server_sock.listen(100)
bluetooth.advertise_service( server_sock, "MyService",
service_classes = [ bluetooth.SERIAL_PORT_CLASS ],
profiles = [ bluetooth.SERIAL_PORT_PROFILE ] )
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
client_sock.send('Hello')
data = client_sock.recv(1024)
print("received [%s]" % data)
client_sock.close()
server_sock.close()
except:
client_sock.close()
server_sock.close()
On Laptops I have client
import sys
from bluetooth import *
try:
service_matches = find_service(name="MyService",
uuid = SERIAL_PORT_CLASS )
print(service_matches)
if len(service_matches) == 0:
print('Found nothing')
sys.exit(0)
for i in service_matches:
print(i)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print "connecting to ", host
sock=BluetoothSocket( RFCOMM )
sock.connect((host, port))
data = sock.recv(1024)
sock.send("hello!!")
print(data)
sock.close()
except Exception as e:
print(e)
sock.close()
Everything works just fine, however, with one laptop I can repeat the proces between listening and connecting forever. With other Laptot I am able to connect 2-3 times and then I am receiving this error:
in <module>
uuid = SERIAL_PORT_CLASS )
File "C:\Python27\lib\site-packages\bluetooth\msbt.py", line 204, in find_service
addresses = discover_devices (lookup_names = False)
File "C:\Python27\lib\site-packages\bluetooth\msbt.py", line 15, in discover_devices
devices = bt.discover_devices(duration=duration, flush_cache=flush_cache)
IOError: No more data is available.
That means the error happened inside the pybluez function find_service. Interesting is that this happens when it cannot find a device. On the other laptop where this error is never triggered(always connects) but there are no devices ends up always with:
print('Found nothing')
When the error starts to happen after 2-3 succesful connections, I need to restart Raspberry pi to be able to connect again.
Thanks for any help
I have made two scripts to practice using sockets in Python but I have trouble communicating after the connexion is established:
My scripts below :
Server.py
#!/usr/local/bin/python3.5
import socket, sys
HOST = 'myIP'
PORT = 50000
counter = 0
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
mySocket.bind((HOST,PORT))
except socket.error:
print("Socket connection failed.")
sys.exit
while 1:
print("Server ready, waiting for request...")
mySocket.listen(2)
connexion, adress = mySocket.accept()
counter+=1
print("Client connected, adress IP %s, port %s" % (adress[0], adress[1]))
msgServeur="Connected to server PytPyt. You can send messages."
connexion.send(msgServeur.encode("Utf8"))
msgClient = connexion.recv(1024).decode("Utf8")
while 1:
print("C>", msgClient)
if msgClient.upper() == "END" or msgClient == "":
break
msgServeur = input("S> ")
connexion.send(msgServeur.encode("Utf8"))
msgClient = connexion.recv(1024).decode("Utf8")
connexion.send("end".encode("Utf8"))
print("Connexion finished.")
connexion.close()
ch=input("<R>etry <T>erminate?")
if ch.upper() =='T':
break
Client.py
#!/usr/local/bin/python3.5
import socket, sys
HOST = 'myIP'
PORT = 50000
mySocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
mySocket.connect((HOST, PORT))
except socket.error:
print("Connexion failed.")
sys.exit()
print("Connexion established with server.")
msgServeur = mySocket.recv(1024).decode("Utf8")
while 1:
if msgServeur.upper == "END" or msgServeur == "":
break
print("S>", msgServeur)
msgClient=input("C> ")
mySocket.send(msgClient.encode("Utf8"))
msgServeur = mySocket.recv(1024).decode("Utf8")
print("Connexion terminated.")
mySocket.close()
When I execute the two scripts I have the result below :
Server :
myPrompt : ./Server.py &
Server ready, waiting for request...
Client connected, adresse IP myIP, port 53551
Client :
myPrompt : ./Client.py &
Connexion established with server.
S> Connected to server PytPyt. You can send messages.
C> hello
-bash: hello: command not found
[1]+ Stopped ./Client.py
It seems that my message is executed as a bash command and not a message to send. However if I run the job again it will work :
Client :
myPrompt : %
./Client.py
hello
Server :
C> hello
S>
But it fails again right after. I have to run the job again any time I want to send a message.
Do you know where the mistake is?
Actually problem lay in script launching. You using following command
./Client.py &
With & the process starts in the background, so you can continue to use the shell. & detach stdin of your script from terminal. And all that you print in terminal after script launching will be interpreted as bash commands.
Try to use just
./Client.py
I recently wrote a code for a small chat program in Python. Sockets connect fine when I connect them from different terminals on the same system. But the same doesn't seem to happen when I connect them from different computers which are connected over the same Wifi network.
Here's the server code:
#!/usr/bin/env python
print "-"*60
print "WELCOME TO DYNASOCKET"
print "-"*60
import socket, os, sys, select
host = "192.168.1.101"
port = 8888
connlist = []
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "Socket Successfully Created."
connlist.append(s)
s.bind((host,port))
print "Socket Successfully Binded."
s.listen(10)
print "Socket is Now Listening."
except Exception, e:
print "Error : " + str(e)
sys.exit()
def air(sock,message):
for socket in connlist:
if socket != sock and socket != s:
try:
socket.sendall(message)
except:
connlist.remove(socket)
while 1:
read_sockets,write_sockets,error_sockets = select.select(connlist,[],[])
for sock in read_sockets:
if sock == s:
conn, addr = s.accept()
connlist.append(conn)
print "Connected With " + addr[0] + " : " + str(addr[1])
else:
try:
key = conn.recv(1024)
print "<" + str(addr[1]) + ">" + key
data = raw_input("Server : ")
conn.sendall(data + "\n")
air(sock, "<" + str(sock.getpeername()) + ">" + key)
except:
connlist.remove(sock)
print "Connection Lost With : " + str(addr[1])
conn.close()
s.close()
Here's the client script:
#!/usr/bin/env python
print "-"*60
print "WELCOME TO DYNASOCKET"
print "-"*60
import socket, os, sys
host = "192.168.1.101"
port = 8888
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print "Socket Successfully Created."
s.connect((host,port))
print "Connected With " + host + " : " + str(port)
except socket.error, e:
print "Error : " + str(e)
while 1:
reply = raw_input("Client : ")
s.send(reply)
message = s.recv(1024)
print "Server : " + message
s.close()
When I try to connect The client From a different computer I get this error :
Error : [Errno 10060] A Connection attempt failed because the connected party
did not respond after a period of time, or established connection failed
because connected host has failed to respnd.
Your are binding your server only to the local host, so that connections from other hosts are blocked.
Try:
s.bind(("0.0.0.0",port))
I experienced this problem and it took me a many hours to figure this out and I found that (like many others said #Cld) it is your firewall blocking the connection. How I fixed this:
Try to run the server onto the machine that you trying to connect from.
(For example, if you want to run the server on machine A and connect from machine B, run the server on machine B).
If you are on windows (I am not sure about Mac or Linux) it will popup with with the firewall pop-up, which will allow you to give permission to your program to access your private network.
Simply tick the box that says:
"Private networks, such as my home or work network"
and Press allow access
That's it! You've fixed that particular issue. Now feel free to test the server on that machine or close the server and go back to your main machine, which will host that server and run it. You should see that it is now working.
I hope this has helped you, as it is my first post!
EDIT: I also did what #Daniel did in his post with changing the s.bind to include '0.0.0.0'.
I had this same problem for quite sometime, and creating tcp tunnels with ngrok worked for me. You can check it out here
For simple sockets application on your pc, just expose the port you're using by ngrok tcp <port_number>, bind the server socket to localhost and port exposed, and use the url of the tunnel with the port number at client side (typically looks like 0.tcp.us.ngrok.io and a port number).
You can even make multiple tunnels on the free account (needed in my case) by specifying the --region flag: https://ngrok.com/docs#global-locations
I keep getting this error
[Errno 10061] No connection could be made because the target machine actively refused it.
I'm running Windows 7 64 bit, no virus or protection software, and python is allowed through my firewall (I've also tried turning my firewall completely off but same result). When I run the server and use telnet it connects just fine. When I try to connect to the server with the client it fails. Any suggestions as to what I could try to fix this? If you need more information just ask and I'll provide.
Client Code
import socket
import sys
def main():
host = ""
port = 8934
message = "Hello World!"
host = raw_input("Enter IP: ")
#Create Socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print "Failed to create socket. Error code: %s Error Message: %s"%(str(msg[0]),msg[1])
sys.exit()
print "Socket created"
#Connec to Server
print host
print port
s.connect((host,port))
print "You are connected to %s with IP adress of %s"%(host,host)
#Send Data
try:
s.sendall(message)
except socket.error:
print "Failed to send."
#Receive Data
reply = s.recv(4096)
if __name__ == "__main__":
main()
Server Code
# !usr/bin/python
import socket
import sys
HOST = ""
PORT = 8934
def main():
#Setup socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error,msg:
print "Unable to create socket"
sys.exit()
print "Socket created."
#Bind to adress
try:
s.bind((HOST,PORT))
except socket.error,msg:
print "Bind failed. Closing..."
sys.exit()
print "Socket bound."
#Start listening
s.listen(10)
print "Socket Listening"
#Accept connection
conn, addr = s.accept()
print "Connected to %s:%s"%(addr[0],addr[1])
if __name__ == "__main__":
main()
Taking a guess at your indentation, and running your codeā¦ it works just fine.* (As long as I type in 127.0.0.1 when it asks me for the IP.)
Of course the second time I run the client (if I haven't restarted the server) I get a connection-refused error. But that's just because you've coded a server that immediately quits as soon as it gets the first connection. So the second time you run the client, there is no server, so the OS rejects the connection.
You can always run the server again, which lets you run the client one more time. (Except that the server may get a 10048 error when it tries to bind the socket, because the OS is keeping it around for the previous owner. If you see that, look at SO_REUSEADDR in the docs.)
* By "works just fine" I mean that it connects, and prints out the following before quitting:
Socket created
127.0.0.1
8934
You are connected to 127.0.0.1 with IP adress of 127.0.0.1
Obviously it never sends anything to the server or receives anything back, because the server has no send or recv calls, or anything else.