1

I am using a mac to try and send a string wirelessly to a raspberry pi using Bluetooth with python. However, I was not able to find an API that works with mac. I have tried options like pybluez and lightblue, but it seems like they don't work with mac. Is there a solution available for this? Bluetooth communication would be preferable, but I am open to other suggestions. Thanks in advance

Tarun Prakash
  • 53
  • 1
  • 10
  • The simplest would be to use `netcat` or `nc` over wifi as both OSes come with that installed. Just do a `listen` on a random, high-numbered port (>2000) on the Pi and a matching send from the Mac. – Mark Setchell Sep 05 '18 at 16:05

1 Answers1

2

Updated Answer

Still using netcat approach as below, but this is the sender implemented in Python adapted from this answer and works with the receiver below:

#!/usr/local/bin/python3
import socket

def netcat(host, port, content):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, int(port)))
    s.sendall(content.encode())
    s.shutdown(socket.SHUT_WR)
    while True:
        data = s.recv(4096)
        if not data:
            break
        print(repr(data))
    s.close()

netcat('192.168.0.131', 40000, 'Hi')

Here is a matching listener/server as implemented here that works with the sender above or the simple netcat sender from the command line.

#!/usr/bin/env python

import socket
import select

class SocketServer:
    """ Simple socket server that listens to one single client. """

    def __init__(self, host = '0.0.0.0', port = 2010):
        """ Initialize the server with a host and port to listen to. """
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.host = host
        self.port = port
        self.sock.bind((host, port))
        self.sock.listen(1)

    def close(self):
        """ Close the server socket. """
        print('Closing server socket (host {}, port {})'.format(self.host, self.port))
        if self.sock:
            self.sock.close()
            self.sock = None

    def run_server(self):
        """ Accept and handle an incoming connection. """
        print('Starting socket server (host {}, port {})'.format(self.host, self.port))

        client_sock, client_addr = self.sock.accept()

        print('Client {} connected'.format(client_addr))

        stop = False
        while not stop:
            if client_sock:
                # Check if the client is still connected and if data is available:
                try:
                    rdy_read, rdy_write, sock_err = select.select([client_sock,], [], [])
                except select.error:
                    print('Select() failed on socket with {}'.format(client_addr))
                    return 1

                if len(rdy_read) > 0:
                    read_data = client_sock.recv(255)
                    # Check if socket has been closed
                    if len(read_data) == 0:
                        print('{} closed the socket.'.format(client_addr))
                        stop = True
                    else:
                        print('>>> Received: {}'.format(read_data.rstrip()))
                        if read_data.rstrip() == 'quit':
                            stop = True
                        else:
                            client_sock.send(read_data)
            else:
                print("No client is connected, SocketServer can't receive data")
                stop = True

        # Close socket
        print('Closing connection with {}'.format(client_addr))
        client_sock.close()
        return 0

def main():
    server = SocketServer(port=40000)
    server.run_server()
    print('Exiting')

if __name__ == "__main__":
    main()

Original Answer

Try using netcat or nc.

On RaspberryPi, listen on port 40,000 using TCP:

nc -l 40000

On Mac, assuming RaspberryPi has IP address of 192.168.0.131:

echo "hi" | /usr/bin/nc 192.168.0.131 40000 

RaspberryPi shows:

hi
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • This might work, but how do I implement it in python? – Tarun Prakash Sep 05 '18 at 17:58
  • to clarify, I know you can use os.system() to run terminal commands but how would I access the received message on the pi in python? – Tarun Prakash Sep 05 '18 at 18:23
  • Sorry! I completely missed the `python` tag - it didn't occur to me that anyone would want to write Python for such a simple thing! Anyway... try the commands above, until they work, then replace one side (sender/receiver) at a time with Python code. Examples are here https://gist.github.com/leonjza/f35a7252babdf77c8421 and https://stackoverflow.com/a/1909355/2836621 – Mark Setchell Sep 05 '18 at 19:01