LocalSocket写入和刷新以损坏的管道错误结束

时间:2015-07-17 14:05:33

标签: java android sockets google-chrome-devtools unix-socket

我尝试使用Android内部的套接字协议与Chrome的开发人员工具进行通信。 启用了chrome中的USB调试选项,如果我从计算机向前执行adb,则可以与套接字进行交互。但我需要在手机内以编程方式访问它。

这里有一些代码:

package something;

import java.lang.StringBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.BufferedInputStream;

public class SomeService extends Service {
    private final String TAG = SomeService.class.toString();
    private int cnt = 0;
    public static String SOCKET_ADDRESS = "chrome_devtools_remote";
    private String message = "/json";

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "service started");
        Thread t = new Thread(new Runnable() {
             public void run()
             {
                try {
                    LocalSocket receiver = new LocalSocket(LocalSocket.SOCKET_STREAM);
                    receiver.connect(new LocalSocketAddress(SOCKET_ADDRESS, LocalSocketAddress.Namespace.ABSTRACT));
                    StringBuilder request = new StringBuilder().append("GET /json HTTP/1.0\r\n");
                    BufferedOutputStream outbuf = new BufferedOutputStream(receiver.getOutputStream());
                    BufferedInputStream inbuf = new BufferedInputStream(receiver.getInputStream());
                    byte[] buffer = request.toString().getBytes("utf-8");    
                    Log.d(TAG, "outbuf size " + Integer.toString(receiver.getSendBufferSize()));
                    while (true) {
                        Log.d(TAG, "sending " + request.toString());
                        outbuf.write(buffer, 0, buffer.length);
                        outbuf.flush();
                        Log.d(TAG, "sent!");
                        byte[] output = new byte[1000];
                        int read = inbuf.read();
                        int size = 0;
                        int capacity = 0;
                        byte[] bytes = new byte[capacity];

                        // reading
                        while (read != -1) {
                            Log.d(TAG, "recieving");
                            capacity = (capacity * 3)/2 + 1;
                            byte[] copy = new byte[capacity];
                            System.arraycopy(bytes, 0, copy, 0, bytes.length);
                            bytes = copy;
                            bytes[size++] = (byte)read;

                            // read next byte
                            read = inbuf.read();
                        }
                        Log.d(TAG, new String(bytes));
                        try {
                            Thread.sleep(3000);    
                        } catch(Exception e) {

                        }

                    }                 

                } catch (IOException e) {
                    Log.e(getClass().getName(), e.getMessage(),e);
                }
            }
        });
        t.start();
        return Service.START_STICKY;
    }
}

这总是会导致此错误:

Starting service: Intent { cmp=something/.MyService (has extras) }
D/class something.MyService(18717): service started
D/class something.MyService(18717): outbuf size 163840
D/class something.MyService(18717): sending GET /json HTTP/1.0
E/something.MyService$1(18717): Broken pipe
E/something.MyService$1(18717): java.io.IOException: Broken pipe
E/something.MyService$1(18717):  at android.net.LocalSocketImpl.writeba_native(Native Method)
E/something.MyService$1(18717):  at android.net.LocalSocketImpl.access$600(LocalSocketImpl.java:33)
E/something.MyService$1(18717):  at android.net.LocalSocketImpl$SocketOutputStream.write(LocalSocketImpl.java:134)
E/something.MyService$1(18717):  at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
E/something.MyService$1(18717):  at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
E/something.MyService$1(18717):  at something.MyService$1.run(RTCService.java:49)
E/something.MyService$1(18717):  at java.lang.Thread.run(Thread.java:841)

套接字肯定是打开的,我正在使用套接字对象的isConnected()方法进行检查。我有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,似乎你没有在你的接收器对象上调用setSendBufferSize / setReceiveBufferSize,这样做后我的问题得到了进一步解决,虽然它对我来说还不是一个完整的解决方案。

我试图发送到我自己的原生抽象套接字,到目前为止,似乎一次只写1个字节,因为我在我的“服务器”端只调用一次recv,管道在第1个字节后被破坏。

换句话说,我期待发送(“HELLO”),但Java流实现似乎正在发送(“H”),发送(“E”),发送(“ L “),发送(” L “),发送(” O“)。

编辑:

如果有帮助,这里的代码最终为我工作:

LocalSocket socket = new LocalSocket ( LocalSocket.SOCKET_STREAM );
socket.connect ( new LocalSocketAddress ( "someaddress" ) );
if ( socket.isConnected() )
{
     socket.setSendBufferSize ( 128 );
     OutputStream out = socket.getOutputStream();
     out.write ( ... );
     socket.close();
     socket = null;
}

编辑:

在阅读了我的回答评论之后,我认为OP中的问题是请求应该是:

StringBuilder request = new StringBuilder().append("GET /json HTTP/1.0\r\n\r\n");

因为空行标记了请求标头的结束以及服务器数据传输的开始。