【问题标题】:Multi threaded server sending and receiving data between two clients at same time多线程服务器同时在两个客户端之间发送和接收数据
【发布时间】:2023-03-14 04:34:01
【问题描述】:

我需要的是一个服务器,它可以从任何客户端接收数据并将其发送到任何其他连接的客户端。我在整个互联网上寻求帮助,但我尝试的一切都失败了。

我需要服务器在单个端口上运行。我需要它能够以这种格式发送字符串:ID:XPOS:ZPOS:ROTATION:ECT 例如256:56:88:90:Steve。然后我需要其他客户端接收并拆分它。

服务器需要线程化,以便支持多个客户端。

【问题讨论】:

  • 能够支持多个客户端并不一定意味着多线程服务器 - java.nio 允许 IO 多路复用。

标签: java sockets


【解决方案1】:

我设法通过BlockingQueues 做到了这一点。虽然这不是最好的解决方案,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);
            }
        }
    }
}

【讨论】:

  • 从未使用过java nio。无论如何,谢谢,如果你能告诉我和例子,那就太好了。
  • 谢谢,我现在就试一试。如果我遇到任何问题,我可以与您联系吗?
  • @Guitcube 在此处使用 cmets 部分
  • 这很有用。它为我提供了有关套接字如何工作的线索。无论如何,我决定使用一个库。
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 2017-05-01
  • 1970-01-01
  • 2022-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多