I'm trying to setup a RFCOMM client-server communication system between my PC and my Nokia E63. I'm using Python with PyBluez for setting up the server and using PyS60 to program the client on my phone.
However PyBluez is not accepting the connection.
Here the code for the server:
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print "Waiting for connection on RFCOMM channel %d" % port
client_sock, client_info = server_sock.accept()
print "Accepted connection from ", client_info
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print "received [%s]" % data
except IOError:
pass
print "disconnected"
client_sock.close()
server_sock.close()
print "all done"
And here is the code for the client
#!/usr/bin/env python
import socket
class BTReader:
def connect(self):
self.sock=socket.socket(socket.AF_BT, socket.SOCK_STREAM)
addr, services=socket.bt_discover()
print "Discovered: %s, %s" % (addr, services)
port = services[services.keys()[0]]
print port
address=(addr,port)
print "Connecting to", str(address), "..."
self.sock.connect(address)
print "OK."
data = "Hello, World!"
print "Sending data:", data
self.sock.send("Hello World!");
print "SENT."
def close(self):
self.sock.close()
def main():
bt=BTReader()
bt.connect()
bt.close()
if __name__ == '__main__':
main()
When I run both the programs I get this output
1) Server (PC):
Waiting for connection on RFCOMM channel 1 [And it stays there. It doesn't acknowledge the connection. I've checked using WINPDB, even after the phone shows that it has established a connection, the server script remains in the server_sock.accept() loop.]
2) Client (phone):
Discoverd: xx:xx:xx:xx:xx:xx {u'SampleServer':1}
1
Connecting to ('xx:xx:xx:xx:xx:xx', 1) ...
OK.
Sending data: Hello World!
Traceback (most recent call last):
...
...
File "c;\resource\socket.py" , line 409, in send return self._sock.send(data, f, cb)
error: (0, 'Error')
What is causing the problem ??
I know its a year later, but I have another solution. On certain versions of Debian (Raspbian etc) and maybe some others distros. The server_sock.accept() will by default just hang and never accept a connection - even from a paired device! However, a solution to this is really simple. If you go to /etc/bluetooth/main.conf there is a line which is called Disable Plugins. Add a line or change so it looks like this:-
DisablePlugins = pnat
Then restart the Bluetooth service:-
sudo invokeārc.d bluetooth restart
It now MAY have been fixed.
Good luck!
Reference: RFCOMM without pairing using PyBluez on Debian?
You should re-read the Rfcomm-client.py example of the PyBluez library.
I don't know why you are using some random socket instead of the BluetoothSocket object...
However I suspect that is the error. To detail for further readers:
If you look at the client code, he was importing the socket module and using that - that has NOTHING to do with pybluez and is wrong.
As a hint, try to make the 2 examples in the PyBluez library work (client and server) and then make your application.
Sometimes the server pops a window and asks the user to approve the connection. If you run without an X-server then you don't have the chance to see the dialog window and the connection is refused..!! (have spent half a day in the past on this...!!!)
Related
I am trying to connect to a Bluetooth GPS unit from a Raspberry Pi3 using the socket library in python 3. I am able to connect and get data flowing the first time but if I disconnect and then try reconnecting I get:
[Errno 16] Device or resource busy
I have tried placing the connection in a sub process killing it and recreating it (end goal) and I get the same error. If I close and restart the test program it connects no problem.
Here is a test script based on a demo I found, that opens the connection closes it then tries to reconnect for ever. When I try it I get tick tick tick... until I hit ^c to kill it
import io
import socket
from time import sleep
from bluetooth import *
import sys
class SocketIO(io.RawIOBase):
def __init__(self, sock):
self.sock = sock
def read(self, sz=-1):
if (sz == -1): sz=0x7FFFFFFF
return self.sock.recv(sz)
def seekable(self):
return False
# file: l2capclient.py
# desc: Demo L2CAP client for bluetooth module.
# $Id: l2capclient.py 524 2007-08-15 04:04:52Z albert $
if sys.version < '3':
input = raw_input
if len(sys.argv) < 2:
print("usage: l2capclient.py <addr>")
sys.exit(2)
bt_addr=sys.argv[1]
port = 1
print("trying to connect to %s on PSM 0x%X" % (bt_addr, port))
# Create the client socket
sock=BluetoothSocket( RFCOMM )
sock.connect((bt_addr, port))
fd = SocketIO(sock)
bno = 0
for line in fd:
print(line)
bno +=1
if bno >10:
break
sock.shutdown(socket.SHUT_RDWR)
sock.close()
print("closed")
sock=BluetoothSocket( RFCOMM )
not_connected = True
while not_connected:
try:
sock.connect((bt_addr, port))
not_connected = False
except:
sleep(1)
print("tick")
pass
fd = SocketIO(sock)
try:
for line in fd:
print(line)
except IOError:
pass
sock.close()
The SocketIO class is just for convenience of getting data line by line I have tried it with sock.recv(1024) and got the same results.
I have a similar issue. I send data to an HC-05 bluetooth module from my PC using python sockets and a bluetooth RFCOMM socket. Here are a few things which have seemed to improve the debugging situation working with bluetooth...
If you havent already, make your socket a nonblocking socket, it sends out a flag when something goes wrong instead of crashing the program
Make sure you close the connection properly (it seems that you are doing that though)
Make sure that the GPS has no factory settings that prevent you from connecting instantly again. It could maybe have to do with a factory setting/timeout thing not agreeing with the way you request to connect again, and that error could be due to your code and quite possibly in a factory setting if there are any.
I am trying to do wireless communications between a PC (macbook) and a Raspberry Pi 2 using python's socket module (python 2.7). The server is the PC and the client is the Pi.
When I run the code (server first then client) both scripts get stuck on the socket.accept() and socket.connect() methods respectfully.
What is funny is that when I do the reverse (Pi being the server and PC being the client) the code works fine, with data been sent correctly.
The scripts below are meant to loop forever whilst incrementing a counter sent over (I increment the port's after each succesful transfer to avoid '[Errno 48] Address already in use' (probably terrible practice I know))
My client script:
import socket
import sys
def read(port):
s = socket.socket()
host = '10.19.92.44' #(IP address of PC (server))
s.connect((host,port))
try:
msg = s.recv(1024)
s.close()
except socket.error, msg:
sys.stderr.write('error %s'%msg[1])
s.close()
print 'close'
sys.exit(2)
return msg
if __name__ == '__main__':
port = 1025
while True:
print 'hey, checking TCP socket'
data = read(port)
print 'i just read %s' % data
print 'port num is: %d' % port
port = port + 1
My server script:
import socket
import time
def send(data, port):
s = socket.socket()
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print 'Got connection from',addr
c.send(data)
c.close()
if __name__ == '__main__':
port = 1025
num = 1
while True:
print 'hey, sending data'
words = 'helloWorld'
data = words + str(num)
print 'send data: %s' % data
send(data,port)
port = port + 1
num = num + 1
As I mentioned when I swap roles (and replace the server IP address in the client script to the Pis 172.17.33.125) the code works fine...
Any ideas/suggestions?
Thank you very much
I don't have an immediate answer, but I have a couple of ideas.
Your PC and Pi seem to be in different networks. The PC's address is 10.19.92.44, while Pi's is 172.17.33.125. There's a probability that 10.19.92.44 isn't the address you need. In order to find out what is the correct PC IP address to use in the application:
Issue networksetup -listallhardwareports to figure out the name of your wifi interface (should be like en0, en1).
Issue ifconfig, find the wifi interface. The IP address attached to this interface is the one you need.
Another option is to install wireshark on the PC, set up a working system (server-Pi, client-PC) and use wireshark to capture the traffic between the PC and Pi. Wireshark makes it easy to figure out IP addresses of both parties. I would advise to have this program installed whenever you want to debug a complicated networking issue.
I am using TCP sockets to communicate between my server and clients. The server code and socket code are as below:
server:
from socket import *
HOST = 'xx.xx.xx.xx'
PORT = 1999
serversocket = socket(AF_INET,SOCK_STREAM)
serversocket.bind((HOST,PORT))
print 'bind success'
serversocket.listen(5)
print 'listening'
while True:
(clientsocket, address) = serversocket.accept()
print ("Got client request from",address)
#clientsocket.send('True')
data = clientsocket.recv(1024)
print data
clientsocket.send('True')
clientsocket.close()
client:
import socket
import sys
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port on the server given by the caller
server_address = ('xx.xx.xx.xx', 1999)
print >>sys.stderr, 'connecting to %s port %s' % server_address
sock.connect(server_address)
try:
message = 'This is the message. It will be repeated.'
print >>sys.stderr, 'sending'
for x in range (0,1):
name=raw_input ('what is ur name')
print type(name)
sock.send(name)
print sock.recv(1024)
finally:
sock.close()
I am able to communicate with the server from client and able to send and receive data. But the problem I am facing is that I am not able to send and receive data continuously from the server. I have to restart my client code on my laptop to send and receive data again from the server. The way the above client code is working is that when I give a keyboard input, then the socket sends data to server and server responds back. But in the client code, in the for loop if I do two iterations, for the second iteration the data I enter from keyboard is not reaching server. I need to restart my client code to send data again. How do I fix this ?
Also, when once client is connected to the server, the other cannot connect to the server. Any ideas on how to do this ?
You need to design and implement a protocol that specifies what each side is supposed to do and then implement that protocol. You're expecting it to work by magic.
For example:
data = clientsocket.recv(1024)
I suspect you are expecting this to receive a "message". But TCP has no notion of messages. If you need to send and receive messages, you need to define precisely what a "message" is for your protocol and write code to send and receive them.
It may be helpful to look at the specifications for other protocols that use TCP such as HTTP, FTP, or IRC. It really is worth the time to write out a specification of your protocol before you write any code. It will save a lot of pain.
I don't want to make this post long so i get straight to the part i don't understand
this is the code i got from here
i aleady made my own app, but i made it the most awful way!
# Tcp Chat server
import socket, select
#Function to broadcast chat messages to all connected clients
def broadcast_data (sock, message):
#Do not send the message to master socket and the client who has send us the message
for socket in CONNECTION_LIST:
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection may be, chat client pressed ctrl+c for example
socket.close()
CONNECTION_LIST.remove(socket)
if __name__ == "__main__":
# List to keep track of socket descriptors
CONNECTION_LIST = []
RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
PORT = 5000
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# this has no effect, why ?
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('', PORT))
6.listen(10)
# Add server socket to the list of readable connections
CONNECTION_LIST.append(server_socket)
print "Chat server started on port " + str(PORT)
while 1:
# Get the list sockets which are ready to be read through select
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
for sock in read_sockets:
#New connection
if sock == server_socket:
# Handle the case in which there is a new connection recieved through server_socket
sockfd, addr = server_socket.accept()
CONNECTION_LIST.append(sockfd)
print "Client (%s, %s) connected" % addr
broadcast_data(sockfd, "[%s:%s] entered room\n" % addr)
#Some incoming message from a client
else:
# Data recieved from client, process it
try:
#In Windows, sometimes when a TCP program closes abruptly,
# a "Connection reset by peer" exception will be thrown
data = sock.recv(RECV_BUFFER)
if data:
broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '> ' + data)
except:
broadcast_data(sock, "Client (%s, %s) is offline" % addr)
print "Client (%s, %s) is offline" % addr
sock.close()
CONNECTION_LIST.remove(sock)
continue
server_socket.close()
i don't understand the part which uses select and adds a new connections, i guess every time an app tries to connect(myport,myip) a new descriptor is created and this method tries to get connect()ed people? can you explain me?
and i have no idea why the server socket is appended to the socket and why its passed to select! I already read this but i still don't understand
i also don't understand why if sock == server_socket: means there is a new connection, i think its because i still haven't understood select
Select() (like the select() function in C) is somewhat magic. It enables you to wait for a events, without occupying the computer's CPU.
The events, in your case, are the input and output operations of the socket. Imagine you're waiting before closed doors ('you' are the CPU). The (correct) door will open if something useful can be done. Each door leads to the an I/O operation which is added to the CONNECTION_LIST.
While waiting, the CPU doesn't spend time on your program. Whichever door opens first, will wake the CPU, and lets you process the data.
Note: In Linux, select() works on all file operations (such as, in this case sockets). In Windows, this only works on sockets.
Note2: Though sockets work fine, I rather prefer a callback mechanism, such as iowatch from the gio library (part of glib). These will call functions when an operation is necessary.
I have trouble connecting to my own socket on localhost.
s.connect(('127.0.0.1', 4458)) (or "localhost") will just take forever,
and eventually timeout with TimeoutError: [Errno 110] Connection timed out
It should open port 4458, another script will then send some chars to it. Both scripts are supposed to run on the same Raspberry Pi, while 'server' one will execute with sudo (to access the GPIOs) and one without, being a chat bot.
I have no trouble running the server on the Pi (with python 3.4.1) and the client on my Laptop (mac, python 3.4.2).
Also it does work in reverse direction, server script on the laptop and client on the Raspberry.
As final test, it works with both, the server and the client on the said macbook.
Just server + client on the Pi does not work.
The program freezes
My shortened code if it helps:
# $ sudo python3 server.py
__author__ = 'luckydonald'
import socket # server
import time # wait for retry
import threading
class Server(threading.Thread):
port = 4458;
QUIT = False
def run(self):
s = socket.socket()
failed = True
print ("Starting Server on Port %d" % (self.port))
while failed:
try:
s.bind(("", self.port))
except Exception as err:
print(err)
print("Port assignment Failed. Retring in 1 second.")
time.sleep(1)
else:
failed = False
print("Success.")
while not self.QUIT:
print("Listening!")
conn, addr = s.accept() # freezes here
print("Got something: %s , %s" %(str(conn), str(addr)))
while not self.QUIT:
result = conn.recv(1)
print("Got result: " + str(result))
server = Server();
server.daemon = True
server.run();
# server.start();
And for the client:
# python3 cilent.py
s = socket.socket()
print("connecting...")
s.connect(("localhost",4458)) # also tried "172.0.0.1" # freezes here
print("connected!")
s.sendall("+".encode("utf-8"))
s.sendall("-".encode("utf-8"))
s.close()
It will result in this:
What I didn't expected was that localhost/127.0.0.1 did not work.
100% package loss
I had a malformatted entry in my hosts file.
You should check for below items
there is an installed internet information services
iis is running
firewall is grants required ports for running the python.exe