I need to establish wireless communication between an Android tablet and a Raspberry Pi. To do this, I have been writing an Android application that will serve as the client, and I have C code running on the Raspberry Pi for it to be the server. I have already configured the Pi as a wireless hotspot so that it has its own wireless network. I am using the Edimax EW-7811Un usb wireless adapter on the Pi.
I can successfully a message from the Android app to the Pi; however, the Pi is unable to echo the message back to the Android app.
Here is the C server code running on the Raspberry Pi:
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char**argv)
{
int sockfd,n;
struct sockaddr_in servaddr,cliaddr;
socklen_t len;
char mesg[1000];
int returnv;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(3490);
bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
for (;;)
{
len = sizeof(cliaddr);
n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);
printf("-------------------------------------------------------\n");
mesg[n] = 0;
printf("Received the following:\n");
printf("%s",mesg);
printf("-------------------------------------------------------\n");
returnv = sendto(sockfd,mesg,n,0,(struct sockaddr *)&cliaddr,len);
printf("Sent %d bytes.\n", returnv);
}
}
Here is the relevant portion of the Android app code:
package com.example.thehelloworld;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class DisplayMessageActivity extends Activity {
public static final String SERVERIP = "131.215.136.203";
public static final int SERVERPORT = 3490;
public String message;
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message that the user entered.
Intent intent = getIntent();
message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Set the xml file to be activity layout
setContentView(R.layout.displaymessage);
// and start thread to do networking
new Thread(new Client()).start();
}
public class Client implements Runnable {
@Override
public void run() {
try {
// send message to Pi
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
DatagramSocket clientSocket = new DatagramSocket();
byte[] sendData = new byte[1024];
String sentence = message;
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverAddr, SERVERPORT);
clientSocket.send(sendPacket);
// get reply back from Pi
byte[] receiveData1 = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData1, receiveData1.length);
clientSocket.receive(receivePacket);
clientSocket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
I have also included the following permissions in the manifest file:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
The Android code gets stuck at the call to clientSocket.receive(receivePacket)
. However, it seems like the server code finishes sending the message back, as the return value of the sendto call is equal to the number of bytes in the message.
It seems likely that there might be some sort of firewall issue on either the Android side of the Pi side. If this is the case, how might I configure firewall settings so that the right ports/IPs are available?
Any insight on how I can fix this issue so that UDP communication can go both ways would be very appreciated! Also, if there is a better way to send strings between the Android tablet and C code running on the Raspberry Pi, I would love to hear about it.
(Note: I also tried using TCP on both sides for communication, but the Android code would keep getting stuck at the line Socket s = new Socket("131.215.136.240", 3490);
and I couldn't find out why. The code was not throwing any error, but it would get stuck at that line.)
Thanks!