我需要的是一个可以从任何客户端接收数据并将其发送到已连接的任何其他客户端的服务器。我在互联网上四处寻找帮助,但是我尝试的所有方法都失败了。
我需要服务器在单个端口上运行。我需要它能够以以下格式发送字符串:ID:XPOS:ZPOS:ROTATION:ECT
例如256:56:88:90:Steve
。然后,我需要其他客户端来接收并拆分。
该服务器将需要线程化,以便它可以支持多个客户端。
最佳答案
我设法用BlockingQueue
做到了。不过,这并不是最好的解决方案,java.nio
的伸缩性要好得多,但我猜它可以完美地为大约50个客户服务。
您可以为每个客户端创建一个线程,在该线程中,您有一个无限循环,该循环等待队列中的项目从中获取。当队列为空时,所有客户端线程都将被阻塞,因此不会有繁忙的等待。每当需要广播的消息时,请将其添加到客户端的消息队列中。
class Server {
public static final int port = 11111;
private final ServerSocket mServerSocket;
private final Collection<Client> mClients;
private boolean acceptNewClients;
public Server() {
mServerSocket = new ServerSocket(port);
mClients = new ArrayList<Client>();
acceptNewClients = true;
ThreadManager.t.execute(new Runnable() {
@Override
public void run() {
Client c;
while (acceptNewClients) {
// On new client connected
c = new Client(mServerSocket.accept());
mClients.add(c);
}
}
});
}
private void broadcast(String message) {
for (Client c : mClients)
c.sendMessage(message);
}
}
class ThreadManager {
public static final ExecutorService t = Executors.newCachedThreadPool();
}
final class Client implements Runnable {
private Socket mSocket;
private OutputStreamWriter mWriter;
private InputStreamReader mReader;
private boolean mContinueNetworking;
private LinkedBlockingDeque<String> mCommandsToSend;
public Client(Socket s) {
mSocket = s;
mWriter = new OutputStreamWriter(socket.getOutputStream());
mReader = new InputStreamReader(socket.getInputStream());
mCommandsToSend = new LinkedBlockingDeque<String>();
mContinueNetworking = true;
ThreadManager.t.execute(this);
}
public void sendMessage(String message) {
mCommandsToSend.addLast(message);
}
@Override
public void run() {
String message;
while (mContinueNetworking) {
message = mCommandsToSend.take();
try {
mWriter.write(message);
mWriter.write('\n');
mWriter.flush();
} catch (SocketException e) {
e.printStackTrace();
mContinueNetworking = false;
} catch (IOException e) {
e.printStackTrace();
// optional: uncomment for retry in case of failure
// commandsToSend.put(toSend);
}
}
}
}