【问题标题】:putting specific connection in arraylist将特定连接放入arraylist
【发布时间】:2017-09-08 08:03:14
【问题描述】:

我的服务器只需要向所有客户端发送消息。这个问题已经被问过很多次了,解决方案是创建一个数组列表并发送给所有人,只需迭代它调用所需的方法

我采用了在link here 找到的服务器示例

引用如下

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MultiThreadServer implements Runnable {
   Socket csocket;
   MultiThreadServer(Socket csocket) {
      this.csocket = csocket;
   }
   public static void main(String args[]) throws Exception { 
      ServerSocket ssock = new ServerSocket(1234);
      System.out.println("Listening");

      while (true) {
         Socket sock = ssock.accept();
         System.out.println("Connected");
         new Thread(new MultiThreadServer(sock)).start();
      }
   }
   public void run() {
      try {
         PrintStream pstream = new PrintStream(csocket.getOutputStream());
         for (int i = 100; i >= 0; i--) {
            pstream.println(i + " bottles of beer on the wall");
         }
         pstream.close();
         csocket.close();
      } catch (IOException e) {
         System.out.println(e);
      }
   }
}

只是我把run()中的代码改成了

   boolean running = true;
   public void run() {
   while(running){

       try {
           InputStream inFromCli = csocket.getInputStream();
           DataOutputStream out = new DataOutputStream(csocket.getOutputStream());
           conns.add(out);
           DataInputStream in = new DataInputStream(inFromCli);
           String inMsg = in.readUTF();
           String[] words= inMsg.split(" ");
           if(".sendall".equals(words[0])){
               for(DataOutputStream elem : conns){
                   elem.writeUTF("tgthrt");
                   elem.flush();

                 }
           }
     } catch (IOException e) {
          running= false;
     }
   }
}

conns 是一个这样定义的数组列表:

ArrayList<DataOutputStream> conns = new ArrayList<>();

但是,当我迭代时,它不会发送给所有客户端。怎么修改?

【问题讨论】:

  • 您未能发布最重要的部分:ArrayList 如何声明、创建、填充和传递给服务器。
  • 见 conns.add()

标签: java networking server


【解决方案1】:

线程正在运行等待连接的ssock.accept(),因此在打开连接之前永远不会到达您的循环。

我建议创建一个单独的线程来处理连接的 Socket,并在客户端想要连接时使用 Timer 之类的东西重新打开连接。

这样的事情可能会奏效:

private static ArrayList<Timer> listeners = new ArrayList<Timer>();

public static void createSocketListener(CustomSocket s) {
    listeners.add(new Timer());
    listeners.get(listeners.size() -1).scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            // your code logic
        }
    }, 1000, 1000);
}

CustomSocket 将保存对应于 Socket 的实例化 DataInputStream 和 DataOutputStream。您可以简单地通过该线程在多个客户端上继续检查新输入并处理请求。

只需执行以下操作即可使用它:

Timer serverConnection = new Timer();
serverConnection.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        SomeThread.createSocketListener(ssock.accept());
    }
}, 1000, 1000);

【讨论】:

  • 谢谢,我的循环已经到达并且消息被发送,但是只发送给一个客户!
  • 你的循环正确吗?即for(DataOutputStream os : conns) { // logic } - 我仍然认为accept() 正在打破循环
  • stackoverflow.com/questions/12550712/… - 我该如何实现它?
猜你喜欢
  • 2018-02-04
  • 2013-01-12
  • 2018-03-16
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 2013-03-28
  • 1970-01-01
相关资源
最近更新 更多