【问题标题】:JAVA ServerSocket how to synchronize multiple incoming connectionsJAVA ServerSocket如何同步多个传入连接
【发布时间】:2012-12-01 17:47:43
【问题描述】:

我有一个服务器应用程序,它可能会同时接收来自多个客户端的传入连接。它用于从 Internet 接收数据并将其发送到本地的 POS 打印机。代码如下:

public static void main(String args[]) {
    RFServer2 server = new RFServer2();
    while (true) {
        server.run();
    }
}

public RFServer2() {
}

public synchronized void run() {

    try {
        while (printing)
            wait();

        printing = true;
        // 1. creating a server socket
        providerSocket = new ServerSocket(43520);

        // 2. Wait for connection
        System.out.println("Waiting connection...");
        connection = providerSocket.accept();
        System.out.println("Connection received from " + connection.getInetAddress().getHostName());
        connection.setSoTimeout(8000);

        // 3. get Input and Output streams
        out = new ObjectOutputStream(connection.getOutputStream());
        out.flush();
        try {
            in = new ObjectInputStream(connection.getInputStream());
        } catch (Exception e) {
            throw new Exception("Weird connection received, could not read, aborting...");
        }
        // sendMessage("connected");

        // 4. The two parts communicate via the input and output streams

        try {
            message = (String) in.readObject();

            if (message.contains(".")) {
                Socket printerSocket = new Socket(message, 9100);
                printerSocket.setSoTimeout(3000);
                printer = printerSocket.getOutputStream();
                printer.flush();
                sendMessage("connected");

                while (!message.contentEquals("done")) {

                    try {
                        message = (String) in.readObject();
                        if (!message.contentEquals("done")) {
                            printer.write(message.getBytes("UTF-8"));
                            printer.flush();
                        }
                    } catch (Exception e) {
                        System.err.println("Failed to print.");
                        e.printStackTrace();
                        break;
                    }
                }
                this.message = "";
catch (Exception e) {
        System.err.println(e.getMessage());
    } finally {
        // 5: Closing connection
        try {
            this.message = "";
            if (printer != null) {
                System.out.println("Closing connection to the printer...");
                printer.close();
            }
            if (in != null) {
                System.out.println("Closing input...");
                in.close();
            }
            if (out != null) {
                System.out.println("Closing output...");
                out.close();
            }
            System.out.println(new Date() + " - letting server listening...");

            if (providerSocket != null)
                providerSocket.close();

            printing = false;
            notify();
        } catch (Exception ioException) {
            ioException.printStackTrace();
        }
    }
}

好吧,如果我从同一个客户端(例如我的机器)发送多个连接,应用程序会使用 wait() 和 notify() 处理线程,同步它们。 但是,如果我同时从 2 台不同的计算机发送 2 个连接,我的服务器会卡在“从主机收到连接”,并且两个客户端由于超时而掉线。

我只需要解决这个小问题...我已经阅读了这些主题,但未能成功解决我的问题

JAVA threads (different stacks) synchronization

Java thread simple queue

Stopping a ServerSocket accept() loop thread

【问题讨论】:

  • 你的应用是单线程的,为什么需要在这里等待/通知?

标签: java multithreading synchronization thread-safety serversocket


【解决方案1】:

首先你的程序在单线程中运行。

对于我在您的代码中看到的内容,您的问题是您为您参加的每个请求/客户端重置服务器。

你应该使用这样的东西:

        ServerSocket serverSocket = new ServerSocket(port);
        while (true) {
            Socket client = serverSocket.accept();

            //Do your work

            client.close();
        }

在您的情况下,我认为您不需要多线程,但是如果您想使用,请将客户端套接字委托给另一个线程并接受另一个请求...

如果你想使用线程,我建议你创建一个线程池,并创建一个互斥锁来独占访问你的打印机。 一些有用的链接: thread poolmutex

【讨论】:

  • 你说得对,我的程序是单线程的。但是,如果我同时收到 2 个请求,我需要将它们放入队列中并逐个处理它们。当我同时从互联网提交 2 个请求时,您的建议不起作用:(。我将尝试实现线程池和互斥锁。感谢您的帮助。
  • @pulu:出于好奇:“...当我同时提交 2 个请求时,您的建议不起作用...”:什么样的错误您在这种情况下遇到过 /mal 功能吗?
  • 默认情况下,当您设置服务器套接字时,您的收入连接队列设置为 50(您可以使用此构造函数 ServerSocket(int port, int backlog) 更改此数量为 true backlog)。我看到您的客户端丢失有 2 种可能性,1)您将客户端超时设置为一小部分。 2)您仍在重置您的 serverSocket。也可以是其他想法,但请尝试检查我上面提到的这 2 点。如果您的问题尚未解决,请使用您最近的代码更新您的帖子。
  • @nms:我实现了一个线程池,但是没有用。所以我认为问题可能是我的客户端而不是我的服务器。我目前正在客户端工作,以检查发生了什么。谢谢!
  • @alk:我认为发生的情况是一个连接位于另一个连接的中间,结果它们都因超时而被丢弃,从而导致管道中断错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
相关资源
最近更新 更多