Discussion socket must discuss long and short connections
Concept of one, long connection and short connection
1, the concept of long connection and short connection: The former is the entire communication process, the client and server only with a socket object, long-term to maintain the connection of the socket; the latter is a new socket for each request, which closes the socket directly after processing a request. So, in fact, the difference between the length of the connection is: the entire customer and the service side of the communication process is the use of a socket or multiple sockets.
You may think: This is not simple, long connection is not the socket, it is not a short connection is every time each of the new socket is closed. But the fact is not so simple, please continue to look at the following finishing
2, close the stream and keep the socket normal?
Baidu on the internet a bit, found that many people are to close the stream or close the socket to distinguish between long connections and short connections, in fact, the personal feeling that this distinction is not meaningful: because there is a fact that, after the flow closed, Can not send the message (corresponding to close the output stream) or accept (corresponding to close the input stream), because actually closed the corresponding stream, the corresponding connection is closed (here the connection is the channel to send messages!) ), so, the stream shuts down while keeping the socket open, is not reaching the effect of long connection, paste the test code:
123456789101112131415161718192021222324252627282930313233343536373839 |
//发送核心方法
public
String send(String send)
throws
IOException {
String rtn =
null
;
BufferedWriter writer =
null
;
OutputStreamWriter ow =
null
;
OutputStream os =
null
;
try
{
os = socket.getOutputStream();
ow =
new
OutputStreamWriter(os);
writer =
new
BufferedWriter(ow);
char
[] sendChar = send.toCharArray();
ArrayList<Integer> list =
new ArrayList<Integer>();
for
(
char
ch:sendChar){
list.add((
int
)ch);
}
//进行加密操作
list = encry(list);
Iterator<Integer> it = list.iterator();
while
(it.hasNext()){
writer.write(it.next());
}
writer.flush();
rtn =
"发送成功!"
;
}
finally
{
//注意:直接关闭流将会导致socket关闭,只能通过shutdownOutput/input的方式关闭流
//另外,流关闭之后,相当于关闭底层的连接,除非新new个socket,否则和客户端的连接相当于断开
// if(writer!=null){
// writer.close();
// }
// if(ow!=null){
// ow.close();
// }
// if(os!=null){
//os.close();
// }
//socket.shutdownOutput();流关闭之后,相当于关闭底层的连接,除非新<br>new个socket,否则和客户端的连接相当于断开
}
return
rtn;
}
|
This is the core method that I wrote a test to send the message, after closing the corresponding stream (either output or input), the next call to getInputStream or Getoutputstream will throw an exception said: Socket is closed Here is a fact: the socket and the stream are connected, the stream is closed, and the socket is in fact the equivalent of the off state!
In fact, this is also very good understanding, the socket is to rely on the flow to shut down, flow, there is only one, you closed the flow, the socket on the communication channel is closed, and the customer's connection has also been disconnected, so throw the exception is very reasonable.
Therefore, it is impossible for the stream to shut down and require the socket to communicate properly!
So, how to implement a long connection?
The correct way to realize the long connection
1, do not close the stream to achieve long connection?
The previous discussion, the flow closed without closing the socket, or can not reach the effect of long connection, so, to long connection, the flow must not be closed! Then, do not close the stream directly, and then every time you want to send a message directly into the stream into the data, and then call the Flush () method to force the refresh it? In fact, the client is unable to receive the information normally, you will find that even if the server flush, the client will still be in the Read method there blocked! For specific reasons, you can look at the Java API documentation:
The documentation explains if the stream is always available and is not read to the end of the stream (that is, the flow is closed or the network is disconnected!). ), read will always block! In fact, this can be explained clearly: the server side of the Read method will not know when the message is sent out, perhaps I thought the data sent out, but in fact, because of the network delay caused some data delayed arrival (Moreover, it is impossible to reach all the data at the same time), so, The Read method can only keep blocking waiting for the other person's answer. So, how to achieve a long connection?
2, the method of realizing long connection
A, the client automatically exits the open read action. Previously said, even if the server calls the Flush method for output refresh, the client may not be able to exit the read action, it will still block. Therefore, the exit action must have the client program to complete, we can not send a message on the service side and before the refresh of a write-end symbol, the client resolves to the end of the symbol, the change can directly exit read the loop read operation, to avoid blocking.
B, you can call a read method that reads a certain byte into an array (although it seems that this is not very good, after all, the length of each message seems to change), of course, this is only for the message length of the case.
The following code is attached to the implementation of the long connection (in fact, it is more than the previous code to read the end tag symbol)
1234567891011121314151617181920212223242526272829303132333435363738394041 |
//发送核心方法
public
String send(String send)
throws
IOException {
String rtn =
null
;
BufferedWriter writer =
null
;
OutputStreamWriter ow =
null
;
OutputStream os =
null
;
try
{
os = socket.getOutputStream();
ow =
new
OutputStreamWriter(os);
writer =
new
BufferedWriter(ow);
char
[] sendChar = send.toCharArray();
ArrayList<Integer> list =
new
ArrayList<Integer>();
for
(
char
ch:sendChar){
list.add((
int
)ch);
}
//进行加密操作
list = encry(list);
Iterator<Integer> it = list.iterator();
while
(it.hasNext()){
writer.write(it.next());
}
//写入结束标志符号:%
writer.write(
‘%‘
);
writer.flush();
rtn =
"发送成功!"
;
}
finally
{
//注意:直接关闭流将会导致socket关闭,只能通过shutdownOutput/input的方式关闭流
//另外,流关闭之后,相当于关闭底层的连接,除非新new个socket,否则和客户端的连接相当于断开
// if(writer!=null){
// writer.close();
// }
// if(ow!=null){
// ow.close();
// }
// if(os!=null){
//os.close();
// }
//socket.shutdownOutput();流关闭之后,相当于关闭底层的连接,除非新new个socket,否则和客户端的连接相当于断开
}
return
rtn;
}
|
Three, short connection
Short connection is basically nothing to talk about, but every time you close the socket and flow need to pay attention to things:
1, although the front said that the flow is closed, the socket is not available, but we still have to explicitly close the socket, because there is a state in Socekt: called the semi-connected state, when we just use the output stream, we closed the output stream, and can not directly call the Close method, You can only call the shutdown corresponding method (see the Java API for details), but the input stream is still connected (we just don't use it!). At this time, if the soceket is not explicitly closed, it is easy to cause a memory leak, so all stream sockets are explicitly closed
2, short connection and long connection have different use: for a service only need one time to reply to the customer, the use of short connection is simple; However, if the service requires a lot of interactive operation Communication, it is a long connection compared to high performance, after all, the opening and closing of the socket is very performance-consuming.
Iv. Summary
1, the corresponding stream is closed, the corresponding input (out) data channel of the socket is closed, at this time can not achieve long connection effect;
2, close the socket, remember to explicitly close the stream and socket, the order is the line pipe flow and then close the socket.
3, to real first long connection, it is generally necessary to send the end tag symbol to tell the client service side of a message has been sent, otherwise the client will be blocked in the Read method.
Reproduced in original: https://www.cnblogs.com/lcplcpjava/p/6581179.html
How Java implements long connections and short connections for sockets