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 被称为half close。使用半关闭 TCP 使连接的一端能够终止其输出,同时仍从另一端接收数据。让我带您了解socket.shutdownOutput()方法的效果:

  1. 在本地,本地套接字及其输入流在读取时表现正常,但对于写入目的,套接字及其输出流表现得好像套接字已在此结束时关闭:随后对套接字的写入将抛出一个IOException
  2. TCP 的正常连接终止序列(a - 由 ACK 确认的 FIN)排队等待在任何未决数据已发送并确认后发送。
  3. 远程,远程套接字正常运行以用于写入目的,但对于读取目的,套接字的行为就好像它已在此结束时关闭:从套接字进一步读取返回 EOF 条件,即读取计数为 -1 或 an EOFException,具体取决于被调用的方法。
  4. 当本地socket最终关闭时,连接终止序列已经发送,不再重复;如果另一端也已经完成了半关闭,那么套接字上的所有协议交换现在都已完成。

因此我们看到,当收到 EOF 时,可以确保另一端已完成输出关闭。而这个场景socket.shutDownOutput()在另一边完美地实现了。

资料来源:Java 基础网络, Esmond Pitt

于 2013-03-04T17:32:03.713 回答
6

Socket.shutdownOutput()表示客户端已完成通过 TCP 连接发送任何数据。它将发送剩余的数据,然后是一个终止序列,该序列将完全关闭其 OUTGOING 连接。无法发送任何进一步的数据,这也将向您的程序表明请求已完全完成。因此,如果您确定不必发送更多数据,建议您使用它。

但是不需要指示请求完成(如果您有多个请求,您不必一直打开/关闭输出),还有其他方法。

于 2013-03-04T17:04:11.517 回答