在使用多线程的同时如何将接收到的数据从连接的客户端分发到其他连接的客户端?

时间:2019-01-19 16:41:34

标签: java android multithreading server client

我正在设置具有多个客户端的服务器。

我的情况:

当客户端之一将数据发送到服务器时,服务器正在将数据分发到其他客户端。 当服务器从一个客户端接收数据时,服务器会将数据存储在内存中并将其发送给其他客户端。

问题:

我正在使用多线程将多个客户端连接到我的服务器。 当客户端将数据发送到服务器时,我不知道如何将数据传递到其他“连接的客户端线程”。

Server.java

public static void main(String[] args) {

        int port = 3434;
        try (ServerSocket serverSocket = new ServerSocket(port)) {

            System.out.println("Server is listening on port " + port);

            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("New client connected");

                new ServerThread(socket).start();
            }

        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
            ex.printStackTrace();
        }
    }

ServerThread.java

public class ServerThread extends Thread {
    private Socket socket;
    public Data data;
    public Bartender[] BartenderData;
    public Consumable[] consumableData;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            InputStream input = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, true);


            String text;

            do {
                text = reader.readLine();
                if (text != "bye")
                {
                   data = new Data();
                   Gson gson = new Gson();
                   data = gson.fromJson(text, Data.class);
                }
            } while (!text.equals("bye"));

            socket.close();
        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}

client.java

public class MainActivity extends AppCompatActivity {

    public TextView txtResult;
    public EditText txtInput;
    public TcpClient mTcpClient;
    public Data data;
    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txtResult = findViewById(R.id.txtInfo);
        txtInput = findViewById(R.id.editText);
        createSomeData();
        new ConnectTask().execute("");
    }
    public void btnSend(View view)
    {
        data = new Data();
        if (mTcpClient != null) {
            mTcpClient.sendMessage(new Gson().toJson(new Data()));
        }

    }

    public class ConnectTask extends AsyncTask<String, String, TcpClient> {

        @Override
        protected TcpClient doInBackground(String... message) {

            //we create a TCPClient object
            mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
                @Override
                //here the messageReceived method is implemented
                public void messageReceived(String message) {
                    //this method calls the onProgressUpdate
                    publishProgress(message);
                }
            });
            mTcpClient.run();

            return null;
        }

        @Override
        protected void onProgressUpdate(String... values) {
            super.onProgressUpdate(values);
            //response received from server
            Gson gson = new Gson();
            data = gson.fromJson(values[0], Data.class);
        }
    }

}

我的思维方式:

  1. 客户端发送数据(在本例中为名为“ Data”的对象)。
  2. 服务器接收数据并将数据存储在内存中。
  3. 服务器正在将数据从“连接的客户端线程”传递到主线程中的变量。
  4. 服务器将数据从主线程传递到其他“连接的客户端线程”。
  5. 其他客户端是最新的。

1 个答案:

答案 0 :(得分:0)

  • 创建一个列表以存储套接字。
  • 启动线程以处理客户端请求。
  • 接收消息循环列表(不包括当前套接字)以将消息发送给其他客户端时。

我这样修改您的代码:

public class ServerThread extends Thread {
    private static List<Socket> sockets = new ArrayList<>();
    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
        sockets.add(socket);
    }

    @Override
    public void run() {
        try {
            // assume the data from client is a string  Hello Server
            String data = "Hello Server";
            // send data to other client
            for (Socket sc : sockets) {
                if (!sc.equals(socket)) {
                    sc.getOutputStream().write(data.getBytes());
                }
            }

        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
        }
    }
}