java socket.shutdownOutput() 的目的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15206605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
purpose of socket.shutdownOutput()
提问by Aravind Yarram
I am using the below code to send data to a tcp server. I am assuming that I need to use socket.shutdownOutput()
to properly indicate that the client is done sending the request. Is my assumption correct? If not please let me know the purpose of shutdownOutput()
. Also appreciate any further optimizations I can make.
我正在使用以下代码将数据发送到 tcp 服务器。我假设我需要使用socket.shutdownOutput()
来正确指示客户端已完成发送请求。我的假设正确吗?如果不是,请让我知道shutdownOutput()
. 也感谢我可以做的任何进一步优化。
Client
客户
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()
Server
服务器
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()
}
采纳答案by Leander
Socket.shutdownOutput()
means that the client is finished sending any data through the TCP connection. It will send the remaining data followed by a termination sequence which will completely close its OUTGOING connection. It is not possible to send any further data, which will also indicate to your program that the request is completely finished. So its recommended if you are sure you don't have to send any more data.
Socket.shutdownOutput()
意味着客户端完成了通过 TCP 连接发送任何数据。它将发送剩余的数据,然后是一个终止序列,该序列将完全关闭其 OUTGOING 连接。无法发送任何进一步的数据,这也将向您的程序表明请求已完全完成。因此,如果您确定不必发送更多数据,则建议使用它。
But it's not needed to indicate that the request is finished (you don't have to open/close the output all the time if you have multiple requests), there are other ways.
但是不需要表明请求已完成(如果有多个请求,则不必一直打开/关闭输出),还有其他方法。
回答by Vishal K
I am using the below code to send data to a tcp server. I am assuming that I need to use socket.shutdownOutput() to properly indicate that the client is done sending the request. Is my assumption correct?
我正在使用以下代码将数据发送到 tcp 服务器。我假设我需要使用 socket.shutdownOutput() 来正确指示客户端已完成发送请求。我的假设正确吗?
YESYour assumption is correct. And this output ShutDown is known as half close. Using half close the TCP provides the ability for one end of the connection to terminate its output, while still receiving data from the other end. Let me walk you through the effects of socket.shutdownOutput()
method :
是你的假设是正确的。这个输出 ShutDown 被称为half close。使用半关闭 TCP 可以让连接的一端终止其输出,同时仍然从另一端接收数据。让我带您了解socket.shutdownOutput()
方法的效果:
- Locally, the local socket and its input stream behave normally for reading
purposes, but for writing purposes the socket and its output stream behave
as though the socket had been closed by this end: subsequent writes to the
socket will throw an
IOException
- TCP's normal connection-termination sequence (a - FIN acknowledged by an ACK) is queued to be sent after any pending data has been sent and acknowledged.
- Remotely, the remote socket behaves normally for writing purposes, but for
reading purposes the socket behaves as though it had been closed by this
end: further reads from the socket return an EOF condition, i.e. a read count
of -1 or an
EOFException
, depending on the method being called. - When the local socket is finally closed, the connection-termination sequence has already been sent, and is not repeated; if the other end has already done a half-close as well, all protocol exchanges on the socket are now complete.
- 在本地,本地套接字及其输入流的行为正常用于读取目的,但出于写入目的,套接字及其输出流的行为就好像套接字已在此结束时关闭:对套接字的后续写入将抛出
IOException
- TCP 的正常连接终止序列(a - 由 ACK 确认的 FIN)在任何未决数据被发送和确认后排队等待发送。
- 远程,远程套接字的行为通常用于写入目的,但出于读取目的,套接字的行为就好像它已在此结束时关闭:从套接字进一步读取返回 EOF 条件,即读取计数为 -1 或 an
EOFException
,具体取决于被调用的方法。 - 当本地socket最终关闭时,连接终止序列已经发送,不再重复;如果另一端也已经完成了半关闭,则套接字上的所有协议交换现在都已完成。
Hence we see that When the EOF is received, that end is assured that the other end has done the output shutdown. And this scenario is perfectly achieved by socket.shutDownOutput()
on the other side.
因此我们看到,当收到 EOF 时,该端确信另一端已完成输出关闭。而这个场景socket.shutDownOutput()
在另一边完美的实现了。
Source: Fundamental Networking in Java,Esmond Pitt
资料来源:Java 基础网络,Esmond Pitt