【问题标题】:Code of new thread after accepting the connection in TCP server isn't executedTCP服务器接受连接后的新线程代码未执行
【发布时间】:2019-11-13 03:48:36
【问题描述】:

我有以下 tcp 服务器:

public class Server {

    private Connection db;
    private Statement statement;
    private ServerSocket socket;

    public static void main(String[] args) {
        Server server = new Server();
        server.initializeServer();
        System.out.println("Server initialized");
        server.listenConnections();
    }

    private void initializeServer() {
        try {
            db = DriverManager.getConnection("jdbc:mysql://localhost:3306/courseworkschema" +
                            "?verifyServerCertificate=false" +
                            "&useSSL=false" +
                            "&requireSSL=false" +
                            "&useLegacyDatetimeCode=false" +
                            "&amp" +
                            "&serverTimezone=UTC",
                    "Sergei",
                    "12345");
            statement = db.createStatement();
            socket = new ServerSocket(1024);
        } catch (SQLException | IOException e) {
            e.printStackTrace();
        }
    }

    private void listenConnections() {
        System.out.println("Listening connections ... ");
        while (true) {
            try {
                Socket client = socket.accept();
                new Thread(() -> {
                    System.out.println("Client accepted");
                    try {
                        OutputStream outputStream = client.getOutputStream();
                        InputStream inputStream = client.getInputStream();

                        String clientAction;
                        String queryContent;

                        boolean flag = true;

                        while (flag) {
                            byte[] msg = new byte[100];
                            int k = inputStream.read(msg);
                            clientAction = new String(msg, 0, k);
                            clientAction = clientAction.trim();
                            msg = new byte[100];
                            k = inputStream.read(msg);
                            queryContent = new String(msg, 0, k);
                            queryContent = queryContent.trim();
                            System.out.println(clientAction);
                            System.out.println(queryContent);

                            if (clientAction.equalsIgnoreCase("END")) {
                                flag = false;
                            }
                            else if (clientAction.equalsIgnoreCase("LOGIN")) {
                                System.out.println("Login action");
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

创建此服务器是为了与数据库通信。这是我尝试连接到此服务器的方式L

public class LoginController {
    private LoginWindow window;
    private Socket socket;
    private InputStream is;
    private OutputStream os;

    public LoginController() {
        connectToServer();
    }

    public void logInUser(String login, String password) {
        if (!login.isEmpty() && !password.isEmpty()) {
            sendDataToServer("LOGIN");
            sendDataToServer("");
        } else {
            window.showMessageDialog("Fill the fields!", JOptionPane.ERROR_MESSAGE);
        }
    }

    public void attachView(LoginWindow window) {
        this.window = window;
    }

    private void connectToServer() {
        try {
            socket = new Socket("127.0.0.1", 1024);
            System.out.println("Connected");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void sendDataToServer(String res) {
        try {
            os = socket.getOutputStream();
            os.write(res.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

当我运行服务器然后运行客户端时,我在服务器中有这样的日志:

Server initialized
Listening connections ... 

Process finished with exit code -1

所以,我不明白为什么服务器不等待并接受来自客户端的连接,而是在初始化和侦听后关闭。那么,这是怎么回事?我将不胜感激。提前致谢!

UPD

当我运行我的应用程序时,它开始工作,但我发现 Thread 块中的代码没有执行。我什至无法理解,为什么会这样

【问题讨论】:

  • 我的猜测是你可能在将 ServerSocket 绑定到端口 1024 时遇到问题。我从经验中知道,如果你没有正确清理你的套接字,下次你尝试启动时'会发现端口仍然绑定
  • 取决于操作系统,但如果您不是以 root/admin 身份运行,通常不能绑定到端口 1024 或更小。尝试更高的临时端口。
  • @ControlAltDel,更新问题
  • @locus2k,更新问题
  • 你需要.start()在你的线程结束。您只是在创建一个线程对象,但没有调用它来启动 new Thread(()->{}).start()

标签: java tcpclient tcpserver


【解决方案1】:

在您的 private void listenConnections() 中,您正在创建一个 Thread 对象,但您并没有告诉它在创建后启动,因此它不会执行。

您的线程创建行应如下所示:

new Thread(() -> {
  //your code
}).start();

来自 javadocs: https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start()

public void start()

使该线程开始执行; Java 虚拟机调用 该线程的运行方法。结果是两个线程 并发运行:当前线程(从调用返回 到 start 方法)和另一个线程(执行它的运行 方法)。

多次启动一个线程是不合法的。特别是,一个 线程完成执行后可能不会重新启动。

抛出:IllegalThreadStateException - 如果线程已经 开始了。

另见:run()、stop()

【讨论】:

    猜你喜欢
    • 2015-09-10
    • 2013-05-21
    • 2013-09-14
    • 2018-02-18
    • 2021-02-19
    • 2019-04-30
    • 2018-03-09
    • 1970-01-01
    相关资源
    最近更新 更多