【问题标题】:What happens after accepting client in java server socket在 java 服务器套接字中接受客户端后会发生什么
【发布时间】:2015-10-18 20:24:14
【问题描述】:

我有服务器套接字代码,在线程内我这样做:

new Thread(new Runnable() {
    @Override
    public void run() {
        while (true) {
            try {

                Socket socket = my_serverSocket.accept();
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                out.println("hi");
                BufferedReader in = new BufferedReader(new InputStreamReader(socket
                        .getInputStream()));
                String msg = in.readLine();
                System.out.println("message is: " + msg);

                in.close();
                socket.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (SecurityException se) {
                se.printStackTrace();
            }
        }
    }
}).start();

这里重要的地方是我打印“hi”的代码。我感兴趣的是接受如何工作。我的服务器是否由于 socket.close() 行向客户端发送“hi”并关闭套接字,或者连接是否会在其他线程中持续存在。我希望它很清楚,很难解释我的问题。

我需要的是打开连接,然后在服务器代码内部(她在 while 循环或其他地方)从队列中读取数据(即静态公共)并在可用时将数据发送到客户端。当数据不可用时等待,只要数据在队列中就发送它。这是生产者消费者问题,尝试如下:

protected static BlockingQueue<String> q;
q = new LinkedBlockingQueue<String>();

我先声明 BlockedQueue。然后,我想要一些 while 循环或其他什么,而不是打印“hi”。我可以这样做吗:

if ( !q.isEmpty() ){
    try {
        String temp = q.take();
        out.println(temp);
    }catch(InterruptedException e){
        Log.d("yerchik", "couldn't take from queue: "+ e.getMessage());
    }
}

我想阻塞队列自己处理竞争条件。

【问题讨论】:

  • 你在提问之前阅读过Socket#close的javadoc吗?
  • accept() 只是创建套接字。你为什么要关闭套接字?关闭套接字后,不会通过套接字发送任何内容。关闭输入流和套接字的任何原因?其他部分 -> 你想保留 q.isEmpty() 的 if 条件还是 while 条件?
  • @ravindra,是的,我希望我的服务器在整个连接过程中向客户端发送消息,并且我只能有一个客户端。我担心可以在里面写另一个,而我将从队列中读取字符串并将它们发送给客户端。
  • 在服务器套接字上调用 accept() 方法并创建客户端 Socket 后,使用 Socket 变量创建一个新线程。处理该新线程中的所有 IO 操作。

标签: java multithreading sockets


【解决方案1】:

我不确定为什么不能让多个客户端接收消息,但您需要在接受()之后忽略或拒绝其他客户端。每个接受都会创建一个新的套接字连接,我想你可以关闭它。只是不要关闭第一个。

就您的公共静态队列而言,我总是更喜欢使用某种类型的可运行套接字工作程序,并在其构造函数中接收从accept() 返回的套接字。

此外,您将在此套接字工作程序中使用公共方法(例如 queueMessage(Message message))创建一个队列,任何其他线程都可以将其添加到该对象的消息队列中。当消息进入并通过连接的套接字传递它们时,run() 方法将不断循环并使用此消息队列(使用同步访问)。您可以在套接字连接时循环。

同样,多个连接没有问题 - 每个工作线程都有自己的消息队列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-25
    • 2012-06-24
    相关资源
    最近更新 更多