【问题标题】:Multiple write and read over socket通过套接字进行多次读写
【发布时间】:2019-06-05 00:08:39
【问题描述】:

我需要一个应用程序来通过 Wifi 连接电路板。有四个片段,通过单击每个人,我必须写入 arraybyte 或一个字节,然后读取 arrayByte。 第一次,我只是读取arrayBte而没有写入,它工作完美,但是通过单击其他片段,我总是得到null。 这是我的代码:

public class CommsThread extends Thread {
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;

public CommsThread() {
    try {
        socket = new Socket(Const.ip, Const.port);
    } catch (IOException e) {
        e.printStackTrace();
    }
    InputStream tmpIn = null;
    OutputStream tmpOut = null;
    try {
        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();

    } catch (IOException e) {
        Log.d("SocketChat", e.getLocalizedMessage());
    }
    inputStream = tmpIn;
    outputStream = tmpOut;
}

public void run() {
    while (true) {
        try {
            byte[] data = new byte[1];
            inputStream.read(data);
            readData.add(data[0]);
        } catch (IOException e) {
        }
    }
}

 public void write(ArrayList<Byte> bytes) {
        ArrayList list = new ArrayList();
        list.add((byte)0xFE);
    for (byte b: bytes)
    {
        if(b >= 0xFD)
        {
            list.add((byte)0xFD);
            list.add((byte)(b - 0xFD));
        }
        else
            list.add(b);
    }
    list.add((byte)0xFF);
    byte[] listBytes = new byte[list.size()];
    for (int i = 0; i < list.size(); i++) {
        listBytes[i] = (byte)list.get(i);
    }
    try {
        outputStream.write(listBytes);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

我在 asynckTask 类中使用了这段代码:

Const.commsThread = new CommsThread();
                Const.commsThread.start();

通过点击一个片段,我调用了write函数:

//for example
     sendToServer("5");

 public static class WriteToServerTask extends AsyncTask<byte[], Void, Void> {
    protected Void doInBackground(byte[]... data) {
        ArrayList list = new ArrayList();
        list.add((byte)0x05);

        Const.commsThread.write(list);
        return null;
    }
}

public static void sendToServer(String message) {
    byte[] theByteArray = message.getBytes();
    new WriteToServerTask().execute(theByteArray);
}

我没有收到错误,但它永远不会退出到 while 执行写入功能。 提前致谢。

【问题讨论】:

  • Const 是一类静态变量。

标签: android multithreading sockets tcp


【解决方案1】:

我得到了答案:

起初:

new CreateCommThreadTask().execute();

CreateCommThreadTask:

   private class CreateCommThreadTask extends AsyncTask<Void, Integer, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            try {
                // ---create a socket---
                //  Const.socket = new Socket(Const.ip, Const.port);
                Socket socket = new Socket("192.168.4.1", 8888);
                Const.commsThread = new CommsThread(socket);
                Const.commsThread.start();

            } catch (UnknownHostException e) {
                Log.d("Sockets", e.getLocalizedMessage());
            } catch (IOException e) {
                Log.d("Sockets", e.getLocalizedMessage());
            }
            return null;
        }
    }

通讯线程:

public class CommsThread extends Thread {
    private Socket socket;
    private InputStream inputStream;
    private OutputStream outputStream;
    public static ArrayList<Byte> readData = new ArrayList<Byte>();

    public CommsThread(Socket sock) {
        socket = sock;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

        } catch (IOException e) {
            Log.d("SocketChat", e.getLocalizedMessage());
        }
        inputStream = tmpIn;
        outputStream = tmpOut;
    }

    public void run() {
        while (true) {
            try {
                byte[] data = new byte[1];
                inputStream.read(data);
                readData.add(data[0]);

            } catch (IOException e) {

            }
        }

    }

    // send data to the remote device---
    public void write(ArrayList<Byte> bytes) {
        ArrayList list = new ArrayList();
        list.add((byte) 0xFE);
        for (byte b : bytes) {
            if (b >= 0xFD) {
                list.add((byte) 0xFD);
                list.add((byte) (b - 0xFD));
            } else
                list.add(b);
        }
        list.add((byte) 0xFF);
        byte[] listBytes = new byte[list.size()];
        for (int i = 0; i < list.size(); i++) {
            listBytes[i] = (byte) list.get(i);
        }
        try {
            outputStream.write(listBytes);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // ---call this from the main activity to
    // shutdown the connection---
    public void cancel() {
        try {
            socket.close();
        } catch (IOException e) {
        }
    }
}

写:

new WriteToServerTask().execute(theByteArray);

WriteToServerTask:

public static class WriteToServerTask extends AsyncTask<byte[], Void, Void> {
        protected Void doInBackground(byte[]... data) {
            ArrayList list = new ArrayList();
            list.add((byte) 0x05);
            Const.commsThread.write(list);
            return null;
        }
    }

效果很好。

【讨论】:

    【解决方案2】:

    response2 很可能是 null,因为 inputStream.read(Const.data2) 返回 -1。例如,如果套接字已被对等方 (docs) 关闭,就会出现这种情况。

    您应该为 -1 情况添加一些额外的处理。还可以考虑添加一些日志记录,以帮助您了解程序中发生的事情。

    run() 将在您调用Const.commThread.start() 后不久异步执行。

    【讨论】:

    • 感谢您的帮助,我检查了socket.isConnected() 并且是真的然后我添加了result=e.tostring() 我的意思是IOException e,但是result=null
    • 如果您已读取所有数据(可能没有)并且对等方已关闭连接,则会出现这种情况。如果您关闭了自己的套接字,您将获得SocketException: socket closed。它必须是一个阻塞套接字,因为他正在使用流。
    • @user207421 进行了一些更正。感谢您指出这一点。
    • user207421,我没听懂你的意思。我是 androdi 的新手。我更改了代码,但写入函数从未执行。你能帮帮我吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 2013-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多