Before doing a game development for a period of time, using mina communication framework, afraid of long forgotten, here to sort out the knowledge points. The first is to understand his core nio, but to say this, we must first understand bio. Before jdk1.4, blocking-BIO was used. After jdk1.4, NIO-non-blocking IO was introduced. After jdk1.7, AIO-asynchronous non-blocking IO was introduced. BIO believes that everyone has written in their introduction:
In bio programming, a thread is needed to loop to check whether there is a new socket connection. After the connection, the socket is put into a new thread or connection pool. So the number of sockets and threads M: N, M > N. Bio is face-to-face flow. Links, reads and writes are synchronously blocked. This means that when the other party processes the data slowly or the network transfers the data slowly, the thread processing the request is blocked and waiting. Even if the thread pool is used, the thread will be eaten up and subsequent processing will not work properly.while(true){ Socket s = socket.accept(); //Operation s //new Thread(s); //s.read(); //s.write(); }
nio socket programming
Channels and corresponding events are registered with selector. There are four kinds of events: the server receives the client connection, the client connects the server, reads the event, and writes the event. All events can share a selector or can be separated.
The selector selector also needs a thread to rotate training to see if there is a ready channel. When the original program wants to read the data from the other party, it needs to block and wait for the other party's stream data to be assembled on the network card before it can be read. It's like you have to go downstairs and wait for the courier to deliver it to you. When a program needs to read data, it only needs to register the event and channel to the selector. The selector has been rotating the data you care about. When the data arrives at the network card and is ready, it is rotated out. When there is a ready channel, the data in the channel is read into the buffer. Whether the channel is ready or not depends on the operating system.while(true){ int n=selector.select(); if(n>0){ //Remove Ready Channel //Judging the type of event //Handling corresponding events } }
Sticking and breaking of mina communication framework
What is the problem of sticking and breaking?
TCP is a face-to-face byte stream, and its messages are boundless, just like articles without punctuation, segmentation, and all stick together. Then the sender sends several packets, and the receiver receives them as one package at a time, which is called sticky package. When the data sent by the sender is too large, it is called packet breaking if it does not split into several packets and send them separately. So how to solve it?
1. It is common to use special separators. Like r N and so on.
2. Additionally, add the length of the message to the header.
//Packet public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { Map retm = (Map) message; //map byte array byte[] bytes = gzipMsg(retm); //Message length int len = bytes.length; IoBuffer buf = IoBuffer.allocate(len+4); buf.setAutoExpand(true); //Add the length to the beginning of the message writeInt(buf, len); buf.put(bytes); buf.flip(); out.write(buf); }
To be continued//Unpacking @Override public MessageDecoderResult decodable(IoSession session, IoBuffer buf) { return messageComplete(buf) ? MessageDecoderResult.OK : MessageDecoderResult.NEED_DATA; } private boolean messageComplete(IoBuffer in) { int remaining = in.remaining(); log.info("remaining:" + remaining); if (remaining < 6) return false; //Read the header int len = readInt(in); //Look at the complete news received this time? if (len > in.remaining()) return false; return true;//Continue to accept incomplete achievements } @Override public MessageDecoderResult decode(IoSession session, IoBuffer buf, ProtocolDecoderOutput out) throws Exception { // Try to decode body int length = readInt(buf); if (length < 6) return MessageDecoderResult.NEED_DATA; if (length > 128 * 1024) return MessageDecoderResult.NOT_OK; byte[] message = new byte[length]; buf.get(message); out.write(message); message = null; return MessageDecoderResult.OK; }