In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Editor to share with you how Java uses Socket to correctly read data posture. I hope you will get something after reading this article. Let's discuss it together.
Preface
Usually the most daily development is Http communication, interface debugging is also relatively simple, there is also a more powerful framework support (OkHttp).
The place where individuals usually use socket communication is Android and peripheral communication, Android and ssl service communication, this is based on TCP/IP communication, and the server and device protocols can not be modified, can only communicate in accordance with the relevant message format.
However, there are many problems in using socket to communicate, and there are generally two difficulties:
1. The socket communication layer has to write by itself and the IO stream is used incorrectly, and the data cannot be read or blocked, or the data is read incompletely.
2. Request and response message formats are changeable (json,xml, other), and it is troublesome to parse. If the first two formats are simple, they are handled by the corresponding framework, and other formats generally need to be handled manually.
This paper makes a summary based on the first question, which in the final analysis is caused by the use of read () or readLine ().
Socket usage process
1. Create a socket
2. Connect socket
3. Get the input and output stream
Byte stream:
InputStream mInputStream = mSocket.getInputStream (); OutputStream mOutputStream = mSocket.getOutputStream ()
Character stream:
BufferedReader mBufferedReader = new BufferedReader (new InputStreamReader (mSocket.getInputStream (), "UTF-8"); PrintWriter mPrintWriter = new PrintWriter (new BufferedWriter (new OutputStreamWriter (mSocket.getOutputStream (), "UTF-8")), true)
As for the actual use of byte stream or character stream, it depends on the actual situation. If the return is a string and the read and write is related to the message Terminator (/ r or / n or / rzone), read using the character stream, otherwise the byte stream.
4. Read and write data
5. Close socket
If it is a Socket short connection, you have to go through all five steps above.
If it is a Socket persistent connection, you only need to pay attention to the fourth point, which will encounter the above problems if you use it carelessly.
In the actual development, the long connection is mostly used, one connection, send and receive data many times.
Special note: the input and output stream cannot be closed immediately after reading the data using a long connection. It must be closed when it is not in use at last.
Socket data read and write
When socket is blocked, the read timeout must be set to prevent socket read data from being suspended for a long time when debugging.
MSocket.setSoTimeout (10 * 1000); / / set the client read server data timeout using read () read blocking problem
Daily writing 1:
MOutputStream.write (bytes); mOutputStream.flush (); byte [] buffer = new byte [1024]; int n = 0ByteArrayOutputStream output = new ByteArrayOutputStream (); while (- 1! = (n = mInputStream .read (buffer) {output.write (buffer, 0, n);} / / processing data output.close (); byte [] OutputStream = output.toByteArray ()
There seems to be no problem above, but sometimes there is a mInputStream .read (buffer) blocking, resulting in no execution in the body of the while loop
Daily writing 2:
MOutputStream.write (bytes); mOutputStream.flush (); int available = mInputStream.available (); byte [] buffer = new byte [available]; in.read (buffer)
Although the above does not block, but may not be able to read the data, available may be 0, because it is a network communication, the data may not be returned immediately.
Or modify mInputStream.available () to:
Int available = 0 while while (available = = 0) {available = mInputStream.available ();}
Although the data can be read above, the data is not necessarily complete.
Moreover, the available method returns the estimated available length of the current stream, which is not the total length of the current traffic flow, and is an estimated value; the read method reads data from the stream into buffer, but the read length is from 1 to buffer.length, and returns-1 if the stream ends or encounters an exception.
Final writing (recursive read):
/ * * Recursive read stream * * @ param output * @ param inStream * @ return * @ throws Exception * / public void readStreamWithRecursion (ByteArrayOutputStream output, InputStream inStream) throws Exception {long start = System.currentTimeMillis () While (inStream.available () = = 0) {if ((System.currentTimeMillis ()-start) > 20 * 1000) {/ / exit throw new SocketTimeoutException ("timeout");}} byte [] buffer = new byte [2048]; int read = inStream.read (buffer); output.write (buffer, 0, read) SystemClock.sleep (100); / / the delay is below, or there is still a probability of missing int a = inStream.available (); / / check again whether there are available bytes or verify message integrity if (a > 0) {LogUtils.w ("= there are remaining:" + a + "bytes of data unread"); readStreamWithRecursion (output, inStream) }} / * read bytes * * @ param inStream * @ return * @ throws Exception * / private byte [] readStream (InputStream inStream) throws Exception {ByteArrayOutputStream output = new ByteArrayOutputStream (); readStreamWithRecursion (output, inStream); output.close (); int size = output.size () LogUtils.i ("Total number of bytes read this time:" + size); return output.toByteArray ();}
After the above method is read once, the waiting time is fixed, and there may not be data after waiting. If there is no data, the response time is too long, which will affect the user experience. We can optimize it a little bit:
/ * * Recursive read stream * * @ param output * @ param inStream * @ return * @ throws Exception * / public void readStreamWithRecursion (ByteArrayOutputStream output, InputStream inStream) throws Exception {long start = System.currentTimeMillis (); int time = 500 / / milliseconds, depending on the actual situation while (inStream.available () = = 0) {if ((System.currentTimeMillis ()-start) > time) {/ / exit throw new SocketTimeoutException ("timeout");}} byte [] buffer = new byte [2048]; int read = inStream.read (buffer); output.write (buffer, 0, read) Int wait = readWait (); long startWait = System.currentTimeMillis (); boolean checkExist = false; while (System.currentTimeMillis ()-startWait 0) {checkExist = true; / / LogUtils.w ("= there are remaining:" + a + "bytes of data unread"); break }} if (checkExist) {if (! checkMessage (buffer, read)) {readStreamWithRecursion (output, inStream, timeout);} / * * read wait time (in milliseconds * / protected int readWait () {return 100) } / * read bytes * * @ param inStream * @ return * @ throws Exception * / private byte [] readStream (InputStream inStream) throws Exception {ByteArrayOutputStream output = new ByteArrayOutputStream (); readStreamWithRecursion (output, inStream); output.close (); int size = output.size (); LogUtils.i ("Total number of bytes read this time:" + size) Return output.toByteArray ();}
The above delay rate has been greatly reduced, and this method is currently being used to read, and there is no more incomplete and blocking of data reading. However, this kind of reading should also pay attention to the problem of message Terminator and when to finish reading.
Use readreadLine () to read blocking problems
Daily writing:
MPrintWriter.print (sendData+ "\ r\ n"); mPrintWriter.flush (); String msg = mBufferedReader.readLine (); / / processing data
If you are careful to find that you add a Terminator when sending data, if you do not add a Terminator, it will block readLine (), fail to read any data, and finally throw a SocketTimeoutException exception.
Pay special attention to:
Message Terminator: add it according to the requirements of the actual server. If necessary, ask the back-end developer or check the interface documentation for instructions.
Otherwise, it will waste a lot of valuable time in interface debugging and affect the later function development.
Note when using readLine ():
1. Note that there are / r or / n or / rzone in the data read.
This sentence means that after the server has written the data, the message Terminator / r or / n or / rzone will be printed.
Similarly, when the client writes the data, it also prints the message Terminator so that the server can read the data.
2. It will block when there is no data, and return null only when the data flow is abnormal or disconnected.
3. When using data streams such as socket, avoid using readLine () to avoid blocking for a newline / carriage return
The above long connection is to send data and read data once, which ensures the integrity of the current communication and needs to be processed synchronously when necessary.
There is also a long connection, where the client opens a thread loop to block and wait for the server data to send data, such as message push. The usual use of long connections is to use different commands to send and receive data to complete different tasks.
After reading this article, I believe you have a certain understanding of "how Java uses Socket to correctly read data posture". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.