0

I am creating a TCP server on raspberry pi so that i can control it from my android phone over WIFI. I have connected both the pi and the phone to my WIFI router.

import socket
from cookieLED_FINAL import callLED

host = '192.168.100.100'
port = 5560

def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created.")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    print("Socket bind complete.")
    return s

def setupConnection():
    s.listen(1) # Allows one connection at a time.
    conn, address = s.accept()
    print("Connected to: " + address[0] + ":" + str(address[1]))
    return conn

def storeFile(filePath):
    picFile = open(filePath, 'wb')
    print("Opened the file.")
    pic = conn.recv(1024)
    while pic:
        print("Receiving picture still.")
        picFile.write(pic)
        pic = conn.recv(1024)
    picFile.close()

def dataTransfer(conn):
    # A big loop that sends/receives data until told not to.
    while True:
        # Receive the data
        data = conn.recv(1024) # receive the data
        data = data.decode('utf-8')
        # Split the data such that you separate the command
        # from the rest of the data.
        dataMessage = data.split(' ', 1)
        command = dataMessage[0]
        if command == 'GET':
            reply = GET()
        elif command == 'REPEAT':
            reply = REPEAT(dataMessage)
        elif command == 'STORE':
            print("Store command received. Time to save a picture")
            storeFile(dataMessage[1])
            print("FINISHED STORING FILE")
            break
        elif command == 'LED_ON':
            callLED()
            reply = 'LED was on'
        elif command == 'EXIT':
            print("Our client has left us :(")
            break
        elif command == 'KILL':
            print("Our server is shutting down.")
            s.close()
            break
        else:
            reply = 'Unknown Command'
        # Send the reply back to the client
        conn.sendall(str.encode(reply))
        print("Data has been sent!")
    conn.close()


s = setupServer()

while True:
    try:
        conn = setupConnection()
        dataTransfer(conn)
    except:
        break

When using IP:

192.168.100.100 :

[Errno 99] Cannot assign requested address

127.162.100.100 or 0.0.0.0: The socket is being created but android client is not getting connected.

On my android phone i am using an app named TCP/UDP Test Tool which I downloaded from play store.

I am new on linux as well as on raspberry pi 3 B+.

OS: RASPBIAN

PROGRAMMING LANGUAGE: PYTHON 3.5

closed as unclear what you're asking by goldilocks Jun 11 '18 at 12:22

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I take it 192.168.100.100 is the RPi's IP address? – Jaromanda X Jun 11 '18 at 9:55
  • "0.0.0.0: The socket is being created but android client is not getting connected" -> I take this to mean that using 0.0.0.0 doesn't throw "Errno 99", it which case you need to explain exactly what "not getting connected" means. It times out? The connection is refused? You should also edit your question to show you have fixed the host address problem (there is no point using the 192.168... address) and make it clear that the TCP test tool can send the kind of messages you want and you intend to use it as the client. – goldilocks Jun 11 '18 at 12:22
1

1) You can set host to host = '0.0.0.0' or host=''.

2) You don't really need an Android phone to test the socket connection, all you need is to run another session of terminal on your computer or even on the same Raspberry Pi and using command curl http://192.168.100.100:5560 to be as a client(assuming this is your Raspberry Pi's IP address and where the socket server is running).

3) There are a couple of issues with your code. First issue is that you parse the HTTP Header incorrectly. When a GET request is sent by the client (using curl http://192.168.100.100:5560/LED_ON command in this example), the header looks like this:

 GET /LED_ON HTTP/1.1
 Host: 192.168.100.100:5560
 User-Agent: curl/7.54.0
 Accept: */*

which is one long string as:

'GET /LED_ON HTTP/1.1\r\nHost: 192.168.100.100:5560\r\nUser-Agent: curl/7.54.0\r\nAccept: */*\r\n\r\n'

Your code command = dataMessage[0] will already return 'GET' (unless you are send a POST request from a client), not the URL path that you wished to use as the command.

data = data.decode('utf-8')
dataMessage = data.split(' ', 1)  //this generates a list like ['GET', '/LEN_ON and a long string']
command = dataMessage[0]

What you really need to do is:

data = data.decode('utf-8')
dataMessage = data.split(' ')  //this generates a list ['GET','/LED_ON','..','..',]
command = dataMessage[1]

which will return:

/LED_ON

4) When you send the data back to the client, for socket communication, you need to add \r\n explicitly at end of the message, or else the client will assume the message is not end yet and will not display anything on the client side. So the example should be like this:

if command == '/':
    reply = 'Welcome\r\n'
elif command == '/LED_ON':
    callLED()
    reply = 'LED was on\r\n'
conn.sendall(reply.encode("utf-8"))
  • No i want to controll the pi using my android phone so running a client on my pi or other computer won't be helpful.And the other thing is I will edit my code later for the inputs and other functions. I want to just know how to set up the server so that i can send message from my phone. – Neil Jun 11 '18 at 11:18
  • i understand that you eventually want to use android to communicate with pi, but for testing purpose, you can do it without. If your server doesn't work, whatever client does not really matter. – hcheung Jun 11 '18 at 11:30
  • There's no where in the OP's question that implies he wants to "parse the HTTP header" or otherwise implement HTTP; I think you've just assumed this based on the fact that the word "GET" is being used in the communication. Notice "REPEAT" is orthogonal to "GET" there, but it is not an HTTP command. If Neil is going to write a TCP client for Android, there's no point in using HTTP -- of course if he doesn't plan to do that, then something web based is a good idea. In which case he should use an existing python web framework! – goldilocks Jun 11 '18 at 12:11
  • Your first point here though is the problem -- the host address should not be the Pi's current LAN address. BTW, I would guess Neil's intention is to use the Android TCP test tool to actually send messages correlating to his simple communication protocol. If that's the case, then he neither has to write an android client, nor use HTTP. – goldilocks Jun 11 '18 at 12:17
  • @goldilocks, true, I just assumed it was HTTP. But if he is implementing TCP, I don't see why his code is not working other than the host IP setting, unless there is some code that he didn't shown. – hcheung Jun 11 '18 at 12:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.