7

以下のコードを使用して、データを tcp サーバーに送信しています。socket.shutdownOutput()クライアントがリクエストの送信を完了したことを適切に示すために使用する必要があると想定しています。私の仮定は正しいですか?そうでない場合は、の目的を教えてくださいshutdownOutput()。また、私ができるさらなる最適化にも感謝します。

クライアント

def address = new InetSocketAddress(tcpIpAddress, tcpPort as Integer)
clientSocket = new Socket()
clientSocket.connect(address, FIVE_SECONDS)
clientSocket.setSoTimeout(FIVE_SECONDS)

// default to 4K when writing to the server
BufferedOutputStream outputStream = new BufferedOutputStream(clientSocket.getOutputStream(), 4096)

//encode the data
final byte[] bytes = reqFFF.getBytes("8859_1")
outputStream.write(bytes,0,bytes.length)
outputStream.flush()
clientSocket.shutdownOutput()

サーバ

ServerSocket welcomeSocket = new ServerSocket(6789)

while(true)
{
    println "ready to accept connections"
    Socket connectionSocket = welcomeSocket.accept()
    println "accepted client req"
    BufferedInputStream inFromClient = new BufferedInputStream(connectionSocket.getInputStream())
    BufferedOutputStream outToClient = new BufferedOutputStream(connectionSocket.getOutputStream())
    ByteArrayOutputStream bos=new ByteArrayOutputStream()

    println "reading data byte by byte"  
    byte b=inFromClient.read()    
    while(b!=-1)
    {        
       bos.write(b)
       b=inFromClient.read()
    }
    String s=bos.toString()

    println("Received request: [" + s +"]")   

    def resp = "InvalidInput"
    if(s=="hit") { resp = "some data" }

    println "Sending resp: ["+resp+"]"

    outToClient.write(resp.getBytes());
    outToClient.flush()
}
4

2 に答える 2

10

以下のコードを使用して、データを tcp サーバーに送信しています。クライアントがリクエストの送信を完了したことを適切に示すために、 socket.shutdownOutput() を使用する必要があると想定しています。私の仮定は正しいですか?

はいあなたの仮定は正しいです。そして、この出力 ShutDown はハーフクローズとして知られています。ハーフ クローズ TCP を使用すると、接続の一方の端で出力を終了しながら、もう一方の端からデータを受信できます。socket.shutdownOutput()methodの効果について説明します。

  1. ローカルでは、ローカル ソケットとその入力ストリームは、読み取り目的では通常どおり動作しますが、書き込み目的では、ソケットとその出力ストリームは、この目的でソケットが閉じられたかのように動作します。ソケットへの後続の書き込みは、IOException
  2. TCP の通常の接続終了シーケンス (a - ACK によって確認される FIN) は、保留中のデータが送信され、確認された後に送信されるようにキューに入れられます。
  3. リモートでは、リモート ソケットは書き込み目的では正常に動作しますが、読み取り目的では、ソケットはこの目的で閉じられたかのように動作します。ソケットからさらに読み取ると、EOF 条件が返されますEOFException。呼び出されるメソッド。
  4. ローカル ソケットが最終的に閉じられるとき、接続終了シーケンスは既に送信されており、繰り返されません。相手側もすでにハーフクローズを行っている場合、ソケット上のすべてのプロトコル交換は完了しています。

したがって、EOF を受信すると、相手側が出力をシャットダウンしたことが保証されます。socket.shutDownOutput()そして、このシナリオは反対側で完全に達成されます.

出典: Java の基礎ネットワーキング、 Esmond Pitt

于 2013-03-04T17:32:03.713 に答える
6

Socket.shutdownOutput()クライアントがTCP接続を介したデータの送信を終了したことを意味します。残りのデータを送信し、その後に終了シーケンスを送信して、OUTGOING接続を完全に閉じます。これ以上データを送信することはできません。これにより、リクエストが完全に終了したこともプログラムに示されます。したがって、これ以上データを送信する必要がないことが確実な場合は、これをお勧めします。

ただし、リクエストが終了したことを示す必要はありません(複数のリクエストがある場合は、常に出力を開いたり閉じたりする必要はありません)。他の方法もあります。

于 2013-03-04T17:04:11.517 に答える