1

複数のクライアントから同時に着信接続を受信する可能性のあるサーバー アプリケーションがあります。インターネットからデータを受信し、ローカルの 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 つの接続を送信すると、サーバーが「ホストからの接続を受信しました」でスタックし、タイムアウトにより 2 つのクライアントがドロップします。

必要なのはこの小さな問題を解決することだけです...それらのスレッドを読みましたが、問題を解決できませんでした

JAVA スレッド (異なるスタック) の同期

Java スレッド単純キュー

ServerSocket accept() ループ スレッドの停止

4

1 に答える 1

2

まず、プログラムはシングルスレッドで実行されています。

私があなたのコードで見ることができるものについては、あなたの問題はあなたが出席するリクエスト/クライアントごとにあなたのサーバーをリセットすることです。

次のようなものを使用する必要があります。

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

            //Do your work

            client.close();
        }

あなたの場合、マルチスレッドは必要ないと思いますが、使用したい場合は、クライアントソケットを別のスレッドに委任して別のリクエストを受け入れます...

スレッドを使用する場合は、スレッドプールを作成し、プリンターに排他的にアクセスするためのミューテックスを作成することをお勧めします。いくつかの便利なリンク: スレッドプールミューテックス

于 2012-12-13T20:08:29.090 に答える