在不同的线程上运行AsynchronousSocketChannel

时间:2019-02-09 05:50:34

标签: java android

我正在尝试使用AsynchronousSocketChannel通过Android中的TCP / IP发送数据,但是却收到android.os.NetworkOnMainThreadException.

当我运行程序并尝试连接到服务器时,将执行失败的connect CompletionHandler方法,并给出NetworkOnMainThreadException

Boost.Asio中,我们在单独的线程中运行io_context。在AsynchronousSocketChannel中需要执行什么操作才能在单独的线程上运行它?

Ethernet.java:

public class Ethernet {
    private String                      ip;
    private int                         port;
    private Queue<String>               recvDataQueue, sendDataQueue;
    private InetSocketAddress           address;
    private String                      readData;
    private InputStream                 in;
    private OutputStream                out;
    private AsynchronousSocketChannel   socket;
    private boolean                     socketAlive, connectionInProgress;
    private ByteBuffer                  readBuffer, sendBuffer;

    Ethernet(String ip, int port) {
        if (port > 65535 && port < 1024)
            port = 6666;
        this.ip = ip;
        this.port = port;
        this.socketAlive = false;
        connectionInProgress = false;
        address = new InetSocketAddress(ip, port);
        this.readBuffer = ByteBuffer.allocate(8192);
    }

    public boolean connect(){
        try{
            if(this.socketAlive)
                return false;
            connectionInProgress = true;
            this.socket = AsynchronousSocketChannel.open();
            this.socket.connect(this.address, null,
                new CompletionHandler<Void, Object>() {
                @Override
                public void completed(Void result, Object attachment) {
                    socketAlive = true;
                    //connectionInProgress = false;
                }
                @Override
                public void failed(Throwable e, Object attachment) {
                    socketAlive = false;
                    //connectionInProgress = false;
                }
            });
            return true;
        }
        catch (Exception e){
            String strErr = e.getMessage();
            Log.e("Exception", strErr);
        }
        return false;
    }

    public long sendData(String writeData){
        try{
            //this.sendBuffer = ByteBuffer.allocateDirect(writeData.length());
            this.sendBuffer = ByteBuffer.wrap(writeData.getBytes(), 0, writeData.length());
            //this.socket.write(writeBuffer, 0, writeData.length()), null,
            this.socket.write(this.sendBuffer, null,
            new CompletionHandler <Integer, Object>() {
                @Override
                public void completed(Integer result, Object attachment) {
                    if (result < 0) {
                        // handle unexpected connection close
                        socketAlive = false;
                        //connectionInProgress = false;
                    }
                    else if(result < sendBuffer.remaining()){
                        // got all data, process the buffer
                        sendBuffer.compact();
                        socket.write(sendBuffer, null, this);    //Test
                    }
                    else{

                    }
                }
                @Override
                public void failed(Throwable e, Object attachment) {
                    if(socket.isOpen()){
                        try{
                            socketAlive = false;
                            socket.close();
                        }
                        catch (Exception ex){
                            String strErr = e.getMessage();
                            Log.e("Exception", strErr);
                        }
                    }
                }
            });
        }
        catch (Exception e){
            String strErr = e.getMessage();
            Log.e("Exception", strErr);
        }
        return -1;
    }

    private void recieveDataSocket() throws Exception {
        this.socket.read(this.readBuffer, null, new CompletionHandler<Integer, Object>() {
            @Override
            public void completed(Integer result, Object attachment) {
                if (result < 0) {
                    socketAlive = false;
                }
                else {
                    //recvQueue.add(readBuffer.toString());
                }
            }
            @Override
            public void failed(Throwable e, Object attachment) {
                if(socketAlive && socket.isOpen()) {
                    try {
                        socketAlive = false;
                        //connectionInProgress = false;
                        socket.close();
                    }
                    catch (final Exception ex){

                    }
                }
            }
        });
    }

    public void disconnect(){
        try {
            if(this.socket.isOpen() && this.socketAlive)
                this.socket.close();
        }
        catch (final Exception ex){
            String strErr = ex.getMessage();
            Log.e("Exception", strErr);
        }
    }

    }
}

MainActivity.java

Ethernet eth = new Ethernet("192.168.1.22", 6666);
while(true) {
    if(!eth.isSocketAlive() && !eth.isConnectionInProgress())
         eth.connect();
    if(!eth.isSocketAlive())
         continue;
    eth.sendData("Hello, World!!!\n");
         eth.disconnect();
}

0 个答案:

没有答案