首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Android两个线程在同一套接字上进行读写

Android两个线程在同一套接字上进行读写
EN

Stack Overflow用户
提问于 2018-06-15 03:07:57
回答 1查看 182关注 0票数 0

我正在尝试运行一个托管服务器的服务,每当它从一个客户端接收数据时,它就会将数据发送到另一个服务器。两者都通过tcp套接字连接,该套接字无限期地保持开放。我在实现正确读取和写入的单个tcp套接字时遇到了问题。

我从两端都接收到了XML,而且它们都定义得很好。一些处理是在收到的xml上完成的,需要将其添加到处理其顺序的队列中。

理想情况下,任一方向上的连接都应该无限期地保持打开状态。

但到目前为止,我看到套接字一直在关闭,这个服务和ServerCode都在关闭套接字,我不知道为什么。

有没有一种方法可以建立到两个端点的连接,并保持套接字无限期打开?

代码语言:javascript
复制
public class routing extends Service {

    private static final String TAG = "[RoutingService]";

    private final IBinder mBinder = new RoutingBinder();
    private final ScheduledThreadPoolExecutor mRoutingThreadPool = new ScheduledThreadPoolExecutor(2);

    private boolean running = false;
    private URI serverAddress;
    private URI clientAddress;

    private Thread serverServiceThread = new ClientService();
    private Thread clientServiceThread = new ServerService();

    private PriorityBlockingQueue<String> clientQueue;
    private PriorityBlockingQueue<String> serverQueue;

    public void setClientAddress(URI testServer) {
        this.serverAddress = testServer;
        this.mRoutingThreadPool.remove(clientServiceThread);
        this.mRoutingThreadPool.scheduleWithFixedDelay(clientServiceThread, 0, 100, TimeUnit.MILLISECONDS);
    }

    public URI getServerAddress() {
        return serverAddress;
    }

    public void setServerAddress(URI testServer) {
        startRunning();
        this.serverAddress = testServer;
        this.mRoutingThreadPool.remove(serverServiceThread);
        this.mRoutingThreadPool.scheduleWithFixedDelay(serverServiceThread, 0, 100, TimeUnit.MILLISECONDS);
    }

    public void startRunning() {
        running = true;
    }

    public void stopRunning() {
        running = false;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        serverQueue = new PriorityBlockingQueue<>();
        clientQueue = new PriorityBlockingQueue<>();
    }

    @Override
    public void onDestroy() {
        stopRunning();
        super.onDestroy();
    }

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

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        clientAddress = URI.create("127.0.0.1:8054");
        serverAddress = URI.create("192.168.2.1:7087");

        startRunning();
        setClientAddress(clientAddress);
        setServerAddress(serverAddress);

        return Service.START_STICKY;
    }

    public class RoutingBinder extends Binder {
        public routing getService() {
            return routing.this;
        }
    }

    class ClientService extends Thread {
        private Socket socket;

        private Runnable ClientReader = new Runnable() {
            @Override
            public void run() {
                if (socket != null && socket.isConnected()) {
                    try (InputStreamReader sr = new InputStreamReader(socket.getInputStream())) {
                        StringBuilder xml = new StringBuilder();
                        char[] buffer = new char[8192];
                        String content = "";
                        int read;
                        while ((read = sr.read(buffer, 0, buffer.length)) != -1) {
                            serverQueue.add(new String(buffer));
                        }
                    } catch (IOException e) {
                        Log.e("clientReader", "Error in testReading Thread.", e);
                    }
                }
            }
        };

        private Runnable ClientWriter = new Runnable() {
            @Override
            public void run() {
                if (socket != null && socket.isConnected()) {
                    while (serverQueue != null && !serverQueue.isEmpty()) {
                        try (OutputStream os = socket.getOutputStream()) {
                            String xml = serverQueue.poll();
                            os.write(xml.getBytes());
                            os.flush();
                        } catch (IOException e) {
                            Log.e("clientWriter", "Error in testReading Thread.", e);
                        }
                    }
                }
            }
        };

        @Override
        public void run() {
            try (ServerSocket server = new ServerSocket(clientAddress.getPort())) {
                try (Socket socket = server.accept()) {
                    socket.setSoTimeout(0);
                    Log.d("SOCKET", String.format("Local Port: %s. Remote Port: %s", socket.getLocalPort(), socket.getPort()));
                    this.socket = socket;
                    //Make the Threads
                    Thread reader = new Thread(ClientReader);
                    Thread writer = new Thread(ClientWriter);
                    //Start the Threads
                    reader.start();
                    writer.start();
                    //Start the Server
                    startRunning();
                    //Join on the Threads so this driver thread will wait until they finish.
                    reader.join();
                    writer.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            stopRunning();
        }
    }

    class ServerService extends Thread {
        private Socket socket;

        private Runnable ServerReader = new Runnable() {
            @Override
            public void run() {
                if (socket != null && !socket.isClosed()) {
                    try (InputStreamReader sr = new InputStreamReader(socket.getInputStream())) {
                        StringBuilder xml = new StringBuilder();
                        char[] buffer = new char[8192];
                        String content = "";
                        int read;
                        while ((read = sr.read(buffer, 0, buffer.length)) != -1) {
                            clientQueue.add(new String(buffer));
                        }
                    } catch (IOException e) {
                        Log.e("ServerReader", "Error in testReading Thread.", e);
                    }
                }
            }
        };

        private Runnable ServerWriter = new Runnable() {
            @Override
            public void run() {
                if (socket != null && socket.isConnected()) {
                    try (OutputStream os = socket.getOutputStream()) {
                        while (clientQueue != null && !clientQueue.isEmpty()) {
                            String xml = clientQueue.poll();
                            os.write(xml.getBytes());
                            os.flush();
                        }
                    } catch (IOException e) {
                        Log.e("ServerWriter", "Error in testReading Thread.", e);
                    }
                }
            }
        };

        @Override
        public void run() {
            if (running) { //Service will keep spinning unti the testService ends the loop
                try (Socket socket = new Socket(serverAddress.getHost(), serverAddress.getPort())) {
                    socket.setSoTimeout(0);
                    Log.d("SOCKET", String.format("Local test Port: %s. Remote test Port: %s", socket.getLocalPort(), socket.getPort()));
                    this.socket = socket;
                    //Make the Threads
                    final Thread writer = new Thread(ServerWriter);
                    final Thread reader = new Thread(ServerReader);
                    //Start the Threads
                    writer.start();
                    reader.start();
                    //Join on the Threads so this driver thread will wait until they finish.
                    writer.join();
                    reader.join();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2018-06-15 06:34:23

关闭套接字的输入或输出流会关闭另一个流和套接字。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50864312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档