Writing audio to server over TCP socket Writing audio to server over TCP socket android android

Writing audio to server over TCP socket


I'll comment on your code piece by piece.

private static ServerSocket serverSocket;

There's no reason for this to be static.

while(true){    try    {        serverSocket = new ServerSocket(port);        serverSocket.setSoTimeout(10000);

The last two lines should be ahead of the loop. This is the reason for the connection refusals, and it will also cause BindExceptions that you haven't mentioned. It isn't clear why you need the timeout.

             Socket clientSoc = serverSocket.accept();             System.out.println("Waiting for client on port " +serverSocket.getLocalPort() + "...");

No you aren't. He's already connected. You were waiting before the accept().

             System.out.println("Just connected to " + clientSoc.getRemoteSocketAddress());             InputStream in = clientSoc.getInputStream();             while(in!=null)

Both the loop and the test are futile. The variable isn't null initially, and there is no way it can ever become null. The loop is futile because the writeToFile() method completely exhausts the input stream, so there is never anything more to read. This will be causing junk data, which you haven't mentioned.

             {                 writeToFile(in);             }             System.out.println("socket");

A pointless message.

             clientSoc.close();

All the code from the line after accept() to here should be executed in a separate thread. The accept loop should do nothing but accept connections and start threads.

          }catch(SocketTimeoutException s)          {             System.out.println("Socket timed out!");

What timed out here was the accept(), as the listening socket is the only socket you've set a timeout on. I doubt that you need this.

             break;          }catch(IOException e)          {             e.printStackTrace();                     System.out.println("some io");

Another futile message.

             break;          } catch (Exception e) {                    System.out.println("some e");

Yet another one. When you get an exception, print the exception. Not some futile message of your own devising. Otherwise debugging becomes a mere guessing game.

            e.printStackTrace();        }       }    }    private void writeToFile(InputStream in) throws IOException {        // Write the output audio in byte        String filePath = "8k16bitMono1.wav";        short sData[] = new short[1024];

Unused. Remove.

        byte[] bData = IOUtils.toByteArray(in);

Don't use this. It wastes space and adds latency. See below for the correct solution.

        FileOutputStream os = null;        try {         os = new FileOutputStream(filePath);        } catch (FileNotFoundException e) {         e.printStackTrace();        }

Poor technique. This catch is in the wrong place. Code that depends on the success of code in a try block should be inside the same try block. At present you are falling through this try-catch as though the exception never happened, which will cause a NullPointerException in the code below.

         System.out.println("Short wirting to file" + sData.toString());

Another pointless message. Misspelt; sData has nothing in it; sData.toString() doesn't print anything useful regardless of the contents; and incorrect, as you aren't writing sData at all.

         try {          os.write(bData, 0, 2048);

This writes exactly 2048 bytes, regardless of the amount read, which could be less or more. If it was less it will throw an ArrayIndexOutOfBoundsException or similar, which I would expect to see on the second call, although you haven't mentioned it, because the array should be zero length on the second and subsequent calls, if any. It should be a loop, of the general form:

int count;byte[] buffer = new byte[8192]; // or more if you likewhile ((count = in.read(buffer)) > 0){    out.write(buffer, 0, count);}

Back to your code:

         } catch (IOException e) {          e.printStackTrace();         }        try {         os.close();        } catch (IOException e) {         e.printStackTrace();        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub      try      {        Thread serverThread = new auServer();        serverThread.run();

This runs the run() method of the thread. It doesn't start a thread. It should be serverThread.start().

        System.out.println("runing");

Misspelt. Until you fix the start/run problem above, you won't see this message until after the server's run() method has exited.

and Client :

private void streamData(byte[] bData) throws UnknownHostException, IOException, InterruptedException {  //bData is byte array to transmit    Thread.sleep(500);

Pointless. Remove. Don't put sleeps into networking code.

    Socket client = new Socket("10.221.40.41",3333);

Don't create a new connection per buffer. Use the same connection for the life of the client.

    OutputStream outToServer = client.getOutputStream();    outToServer.write(bData);    if(!isRecording)        client.close();

This should be unconditional, and it should be elsewhere, along with the creation of the socket.

What could be the problem?

Problems. Plural. Multiple. See above.


The creation of the serversocket must be done outside of the loop.And for parallel connections you need to start a thread per connection.

Also apply the timeout to the established connections. A timeout on the serverSocket will end accepting after the timeout, this is nothing you want in a server.

...public void run() {    ServerSocket serverSocket;    try {        serverSocket = new ServerSocket(port);    } catch (Exception ex) {        ex.printStackTrace();        return;    }    System.out.println("init success");    while (true) {        try {            System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");            final Socket clientSoc = serverSocket.accept();            clientSoc.setSoTimeout(10000);            System.out.println("Just connected to " + clientSoc.getRemoteSocketAddress());            new Thread() {                public void run() {                    try {                        InputStream in = clientSoc.getInputStream();                        writeToFile(in);                    } catch (Exception e) {                        e.printStackTrace();                    } finally {                        try {                            clientSoc.close();                        } catch (Exception ignore) {                        }                    }                }            }.start();        } catch (Exception ex) {            ex.printStackTrace();        }    }}...


I'm guessing your client side is an android application. Once, I tried to read and write data to an android application through a socket connection. Eventually, I did it by using the adb(android debugger bridge).

Lets say, there is a java application which creates a Socket with the port number 1992. And there is an android application, which creates a ServerSocket with the port number 1993.

Here comes the real deal!

Before you start running applications, you need to execute the following command in adb shell (or you can locate your adb in cmd/terminal and execute the command)

adb forward tcp:1992 tcp:1993    

After forwarding the port you can write and read data from java application to android application and wise-versa, using sockets' IO streams.

Desktop application code snippet :

while (flag) {    try {        final Socket socket = new Socket("localhost", 1992);        new Thread(){            @Override            public void run() {                                        while (flag) {                                                try {                        new PrintWriter(socket.getOutputStream(), true).println(new Date().toString());                    } catch (IOException ex) {                        break;                    }                }            }                            }.start();    } catch (IOException ex) {        // need port-forwarding    }}    

Android application code snippet :

while (flag) {    try {        final Socket socket = new ServerSocket(1993).accept();        new AsyncTask<Void, Void, Void>() {            @Override            public Void doInBackground(Void... params) {                while (flag) {                    try {                        String line = new BufferedReader(new InputStreamReader(socket.getInputStream())).readLine();                        Log.d("", line);                    } catch (IOException ex) {                        return null;                    }                }                return null;            }        }.execute();    } catch (IOException ex) {        break;    }}    

You can convert your audio to byte array and write it into a output stream. Hope my answer will be useful.