3

Javaソケットの使用例は無数にありますが、どれも同じです。いずれも、クライアントソケットが作成され、一部のテキストが送信され、ソケットが閉じられていることを示しています。

私はいくつかのテストコードを書いています。クライアントにループして、かなりの数のメッセージを送信してもらいたいです。毎回クライアントソケットを閉じて再作成するのはばかげているように思われるので、クライアントソケットを1つ作成し、ループして同じソケットでデータを送信するだけだと思いました。ただし、サーバーソケットは、最後のメッセージがクライアントによって送信され、クライアントソケットが閉じられるまで、受信した内容を出力しません。

サーバ:

Socket  sock;
ClientConnection    client;

ServerSocket ss = new ServerSocket(portNumber);
ss.setSoTimeout(0); // 0=infinite

while (true) {
    sock = ss.accept();
    client = new ClientConnection(sock);
    new Thread(client).start();
    // ClientConnection reads from sock, prints, and closes sock
}

ClientConnection(サーバー側の別のクラス):

public class ClientConnection implements Runnable
{
    private Socket  m_socket;
    private BufferedReader m_in = null;

    public ClientConnection(Socket socket)
    {
        m_socket = socket;

        try {
            InputStream inStream = socket.getInputStream();
            m_in = new BufferedReader(new InputStreamReader(inStream));
        }
        catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public String getMessage()
    {
        String line = null;
        StringBuffer    completeMessage = new StringBuffer();

        try {
            while ((line = m_in.readLine()) != null)
            {
                completeMessage.append(line);
            }
         }
         catch (IOException ioe) {
             ioe.printStackTrace();
             return "";
         }

         return completeMessage.toString();
    }

    public void run()
    {
        try {
            String message = getMessage();
            System.out.println("Received: " +message);
        }
        finally
        {
            try {
                m_socket.close();
            }
            catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}

クライアント:

socket = new java.net.Socket(m_destination, m_portNumber);
outputStream = socket.getOutputStream();
printStream = new java.io.PrintStream(outputStream);

while (more-stuff-to-send)
{
    printStream.print(text);
    printStream.print("\n");
    printStream.flush();
}

prinStream.close();
socket.close();

ClientConnectionは、クライアントを起動したときにサーバーによって作成されますが、クライアントが送信を完了するまで、送信された内容を出力しません。

どこかでポイントが抜けているような気がします。チャットの例は非常に一般的です。チャットクライアントがある場合、チャットサーバーに送信するすべてのメッセージは、クライアントソケットを作成し、メッセージを送信して、ソケットを閉じますか?どういうわけか正しくないようです。

ありがとうございました。

4

1 に答える 1

-1
client = new ClientConnection(sock);

コンストラクターでソケットを渡しています。

だからあなたはすべきではありません:

socket = new java.net.Socket(m_destination, m_portNumber);

コンストラクターからの変数を次のようにキャッシュするだけです。this.sock = sock; リーダーとライターの取得は問題ありません。サーバーも問題ありません。

私はベクトルを使用してメッセージを送信するための同期化されたキューを作成し、while (more-stuff-to-send)ループはスリープよりもキューと id が空であることを確認し、送信するものがある場合は、最初にポップして送信する必要があります。クライアント。

于 2013-03-08T19:18:18.193 に答える