1

最初にマルチスレッド クライアント サーバー アプリケーションを作成し、それを多数のクライアント (それぞれ 1000 メッセージを送信する 100 クライアント) でテストするタスクがあります。そのため、コンソールクライアントサーバーが適切に機能しています。クライアントには、入力用と出力用の 2 つのスレッドがあります。そして今、私はテストを書き始めます。私の意見では、作業スキーマは次のようになるはずです。新しいクライアントの受け入れを待機する必要があるサーバースレッドを実行し、その後、InputThreads を実行して (サーバーに接続し)、サイクルでテストプロトコルを書き込みます。私は正しいですか?

だから私はこのようなものを書きます:

public class ServerLoadTest {
    private static final Logger LOG = Logger.getLogger(ServerLoadTest.class);
    private ExecutorService clientExec = Executors.newFixedThreadPool(100);
    private ExecutorService serverExec = Executors.newFixedThreadPool(100);

    @Test
    public void test() throws IOException, JAXBException, XMLStreamException, ParserConfigurationException, SAXException, InterruptedException {        
        LOG.trace("Start testing");     
        serverExec.execute(new TestServerThread());     

        for (int i = 0; i < 100; i++) { 
            clientExec.execute(new TestClientThread());
        }

        Assert.assertTrue(true);
        LOG.trace("All working fine");
        clientExec.shutdown();
    }

}


class TestClientThread implements Runnable {
    private static final Logger LOG = Logger.getLogger(TestClientThread.class);
    private ExecutorService outputExec = Executors.newFixedThreadPool(2);

    public TestClientThread() {
        new Thread(this);
    }

    @Override
    public void run() {

        try {
            LOG.trace("Starting Socket");
            Socket s = new Socket("localhost", 4444);
            OutputThread spamming = new OutputThread(s, new PrintWriter(s.getOutputStream(), true), new BufferedReader(
                    new InputStreamReader(s.getInputStream())));
            exec.execute(spamming);

            spamming.getOut().println("HO HO Ho HO HO");

            InputThread getSpamAnswer = new InputThread(s, new BufferedReader(new InputStreamReader(s.getInputStream())));
            outputExec.execute(getSpamAnswer);

        } catch (IOException | JAXBException | XMLStreamException | ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
    }
}

class TestServerThread implements Runnable {
    private Server king = mock(Server.class);

    public TestServerThread() {
        new Thread(this);
    }

    @SuppressWarnings("static-access")
    @Override
    public void run() {
        try {
            king.main(null);
        } catch (IOException | JAXBException | ParserConfigurationException | SAXException e) {
            Assert.assertFalse(false);
        }
    }
}

まず第一に、サーバーには多くの LOG.trace がありますが、コンソールには何もありません。デバッグすると、クライアントが接続できないという例外が発生します (時間がなかったと思います)。 . これをどのように同期すればよいですか?

PS サーバーはマルチスレッドであり、多くのクライアントをサポートします。今はソースからテストしたいだけです。

4

1 に答える 1

0

ファイアウォールが開いていて、そのポートで着信接続が許可されていますか?

また、すべての「クライアント」スレッドによって共有されているソケットが 1 つしかないため、実際にはクライアント サーバー アーキテクチャを複製しているわけではありません。これがエラーの原因である可能性があります (複数のスレッドが同じオブジェクト (この場合はストリーム) にアクセスしています)。

個別のプロセスとソケットを使用してクライアント/サーバーのデモを適切にセットアップする方法については、Oracle の次のドキュメントを参照してください: http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html実際に起こり、コードの優れた説明が付属しています。

于 2012-06-14T17:53:47.347 に答える