2

I need to send binary data multiple times with Java Sockets on Android devices. This is a simple object that exports run() and send() methods.

public class GpcSocket {

    private Socket socket;

    private static final int SERVERPORT = 9999;
    private static final String SERVER_IP = "10.0.1.4";

    public void run() {
        new Thread(new ClientThread()).start();
    }

    public int send(byte[] str) {
        try {
            final BufferedOutputStream outStream = new BufferedOutputStream(socket.getOutputStream());
            outStream.write(str);
            outStream.flush();
            outStream.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str.length;
    }

    class ClientThread implements Runnable {
        @Override
        public void run() {
            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                socket = new Socket(serverAddr, SERVERPORT);
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}

For Android Programming, I use Scaloid, and this is the code to send the binary data multiple times. count is given from a parameter. result is Byte[Array] type data, and gpc is initialized in onCreate() method as gpc = new GpcSocket().

gpc.run()
for (i <- 1 to count) {
  val length = gpc.send(result)
  toast(s"Sent: $i $length")
}

The issue is that even when I try to send data multiple times, the receiver receives only one packet. This is what is shown in the server (receiver) side when I send the information 5 times:

55:2015-03-21 03:46:51 86: <RECEIVED DATA>
10.0.1.27 wrote:
56:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
57:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
58:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
59:2015-03-21 03:46:51 0:

My questions are

  • Why is this? Why the receiver receives only one time? The sender shows that it sends the information five times.
  • Do I need to use run() one time only before sending multiple times? Or, do I have to call run() whenever I use send()?

This is the server side code in Python:

import SocketServer
from time import gmtime, strftime

count = 1

class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        global count
        count += 1
        print "%d:%s %d:%s" % (count, strftime("%Y-%m-%d %H:%M:%S", gmtime()), len(self.data), self.data)
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "10.0.1.4", 9999

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()

1 Answer 1

0

From this post: Sending ByteArray using Java Sockets (Android programming) and How to fix java.net.SocketException: Broken pipe?, it seems like that the send() method is wrong.

Close the resources when I'm done using them

I modified the send() to be simple that create the socket and close it when I'm done using it.

public int send(byte[] str) throws IOException {
    InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
    socket = new Socket(serverAddr, SERVERPORT);
    out = socket.getOutputStream();
    out.write(str);
    out.flush();
    out.close();
    socket.close();
    return str.length;
}

Modification in the caller code

The scala code that calls it is modified to invoke the send() method.

// gpc.run()
for (i <- 1 to count) {
  ...
  val length = gpc.send(result)
  println(s"Sent: $i $length")
}

... in initializer
gpc = new GpcSocket()

Change policy mode in Android

Hints from this post: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145), this code should be added for Android device to prevent E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: scaloid.example, PID: 1791 android.os.NetworkOnMainThreadException error.

val policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.