current position:Home>Understand socket communication (IV)

Understand socket communication (IV)

2022-01-26 23:41:18 Android Tang Fu

This is my participation 8 The fourth of the yuegengwen challenge 17 God , Check out the activity details :8 Yuegengwen challenge

understand Socket signal communication ( Four )

The last article explained the basic Socket TCP Long link , This article is right Socket TCP Advanced . Explore its advanced usage and difficulties encountered .

One 、 How to deal with subcontracting sticking

reason

TCP It's in the form of flow , The data are optimized under some conditions

scene

 The current sender sent two packets , The contents of the two packages are as follows :
123456789
ABCDEFGH
 Copy code 

We hope that the recipient's situation is : Received two bags , The first package is :123456789, The second package is :ABCDEFGH. However, the situation of sticking package and subcontracting can not meet the expected situation .

Sticking bag performance

Two packets are sent in a short time interval , For example 0.1 These two packets were sent within seconds , If the package is long enough , Then the receiver will only receive one packet , as follows :

123456789ABCDEFGH
 Copy code 

Sticking package solution

  1. Convention Terminator , Split data when terminator is encountered
  2. Agreed data length , Intercept according to the data length

The simplest way here is
Spell a newline at the end when sending data , Use... When receiving data BufferedReader Of rd.readLine() Receive .

readLine Represents reading the contents of a line .

    @Override
    public void run() {
        while (true) {
            try {
                InputStream inputStream = socket.getInputStream();
                out = socket.getOutputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String str = reader.readLine();
                if (str == null) continue;
                if (listener != null) {
                    listener.onReceive(this, str);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 Copy code 

Subcontracting

Suppose the maximum length of the package is set to 5 byte ( More extreme assumptions , The general length is set to 1000 To 1500 Between ), So without sticking the bag , The receiver will receive 4 A package , as follows :

12345
6789
ABCDE
FGH
 Copy code 

Subcontracting solutions

In the sticky package scenario , Is the need to split data .
In the subcontracting scenario , Multiple packages need to be put together .

resolvent
Agree on a separator , When the data contains the delimiter, it is divided , When no delimiter is included , Just merge the next piece of data , When a delimiter is included, it is split , Extract the data .

Two 、 How to transmit byte and String

2.1 send out

How do we usually send byte and String What about ? Example code :

String str = "hello world"+ "\n";
byte[] bytes =  Picture byte stream ;
//  obtain socket Output stream 
OutputStream out = socket.getOutputStream();
//  Send string 
out.write(str.getBytes());
//  send out byte Array 
out.write(bytes);
 Copy code 

The sending code part is simple , Even if it's String Also turned byte Sent . How do clients distinguish when receiving , How does the client know the received byte Is to convert the string , Or transfer pictures or other types ?

Then you need to improve the code , Add a... At the sending end identification , When the client receives a message , according to identification Distinguish , In this way, the receiving end will know how to turn the message .

Example of modified sender code :

//  Define two identifiers 
final int SOCKET_STRING = 1;
final int SOCKET_BYTE = 2;

public void sendTcpPacket(final byte[] packet, final SendCallback sendCallback) {
        ThreadPool.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    OutputStream outputStream = mSocket.getOutputStream();
                    outputStream.write(" identification ");
                    outputStream.write(packet);
                    if (sendCallback != null)
                        sendCallback.success();
                } catch (Exception e) {
                    if (sendCallback != null)
                        sendCallback.failed();
                }
            }
        });
    }
   
 Copy code 

2.2 receive

Bytes received , Determine what the first identification bit is , The corresponding parsing operation .

 @Override
    public void run() {
        while (true) {
            try {
                InputStream inputStream = socket.getInputStream();
                DataInputStream input = new DataInputStream(inputStream);

                byte[] buffer = new byte[2048];
                // The length of the message 
                int realLength = input.read(buffer, 0, 2048);
                System.out.println(" Length of message received :" + realLength);
                // The actual of the transmission byte[]
                byte[] buffer1 = new byte[realLength];
                for (int i = 0; i < buffer1.length; i++) {
                    buffer1[i] = buffer[i];
                }

                if (listener != null) {
                    listener.onReceive(this, buffer1);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 Copy code 

copyright notice
author[Android Tang Fu],Please bring the original link to reprint, thank you.
https://en.cdmana.com/2022/01/202201262341143074.html

Random recommended