【问题标题】:java server gives up on older clients whenever a new one joins每当有新客户端加入时,Java 服务器都会放弃旧客户端
【发布时间】:2021-12-13 16:29:15
【问题描述】:

首先我想介绍一下我目前的代码:

/**
 App.java:
**/
package org.example;

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


public class App 
{
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(2343);
        } catch (IOException e) {
            System.err.println("Could not listen on 2343");
        }

        try {
            while (true) {
                Socket clientSocket = serverSocket.accept();
                try {
                    new Helper(clientSocket);
                } catch (IOException e) {
                    clientSocket.close();
                }
            }
        } finally {
            serverSocket.close();
        }
    }
}


/**
 Helper.java:
**/
package org.example;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Helper extends Thread {

    public static BufferedReader br;
    public static BufferedWriter bw;
    public static String output = "";

    public Helper(Socket socket) throws IOException {
        System.out.println("user found");
        br = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
        bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
        start();
    }
    @Override
    public void run() {
        while (true) {
            try {
                bw.write("set");
                bw.newLine();
                bw.flush();
                System.out.println(br.readLine()+"\n"+getId());
            } catch (IOException e) {
                System.out.println("Client Lost");
                break;
            }
        }
    }
}


/**
 Cli.java
**/
package org.example2;

import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;

class Cli {
    public static void main(String[] argv) throws Exception {
        BufferedWriter bw;
        Socket clientSocket;

        BufferedReader br;
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));


        clientSocket = new Socket("laith.com.au", 2343);
        bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8));
        br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8));
        while(true){
            String input=br.readLine();
            bw.write(inFromUser.readLine());
            bw.newLine();
            bw.flush();
        }
    }
}

其次,我将显示输出:

App.java

user found
hello world
13
hello world
13
user found
hello world
14
hello world
14
hello world
13
Client Lost
Client Lost

Cli.java (no1 所有用户输入)

hello world
hello world
hello world
hello world

Cli.java (no2 所有用户输入)

hello world
hello world

成绩单:

我启动应用程序:

我启动 Cli 的第一个实例:user found

我在 Cli no1 中输入“hello world”:hello world(换行符)13

我再次在 Cli no1 中输入“hello world”:hello world(换行符)13

我启动第二个 Cli 实例:user found

我在 Cli no2 中输入“hello world”:hello world(换行符)14

我再次在 Cli no2 中输入“hello world”:hello world(换行符)14

我在 Cli no1 中输入“hello world”:hello world(换行符)13

我再次在 Cli no1 中输入“hello world”:

我终止 Cli no1:

我终止 Cli no2:Client Lost(换行符)Client Lost

最后一个问题:

怎么回事,每当我添加另一个客户端连接到服务器时,旧客户端只能在服务器停止响应之前再发送一条消息。

【问题讨论】:

    标签: java multithreading sockets server client


    【解决方案1】:

    这是因为Helper 类中的brbw 被声明为static

    static 表示该字段由该类的所有实例共享。

    因此,当为您的第二个客户端创建第二个 Helper 实例时,这些共享的 brbw 将被此新连接的读取器和写入器覆盖 => 即之后两个 Helper 线程读取和写入这个新连接。

    您会看到来自旧客户端的又一次写入,因为当 brbw 被覆盖时,旧的 Helper 线程已经在 br.readLine() 内部等待来自第一个客户端的传入字符串。
    旧的Helper 线程只有在行到达后才会读取brbw 的新值。

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 2016-04-09
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 2015-02-27
      相关资源
      最近更新 更多