communication

nio server:

package nio.study.serverclient;

 

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.util.Iterator;

 

public class EchoSelectorServer {

//cache size

private static final int BUFSIZE = 256;

//overtime time

private static final int TIMEOUT = 3000;

//port

private static final int PORT = 8888;

 

public static void main(String[] args) throws IOException {

 

Selector selector = Selector.open();

 

ServerSocketChannel listnChannel = ServerSocketChannel.open();

 

listnChannel.socket().bind(new InetSocketAddress(PORT));

 

// Only non-blocking channels can register selectors, so they need to be configured in the appropriate state

 

listnChannel.configureBlocking(false);

 

// Indicate that the channel can be "accepted" during the registration process

 

listnChannel.register(selector, SelectionKey.OP_ACCEPT);

 

Protocol protocol = new EchoProtocol(BUFSIZE);

 

while (true) {

if (selector.select(TIMEOUT) == 0) {

continue;

}

 

Iterator<SelectionKey> keyIter =

 

selector.selectedKeys().iterator();

 

while (keyIter.hasNext()) {

 

SelectionKey key = keyIter.next();

System.out.println("isAcceptable:"+key.isAcceptable());

 

if (key.isAcceptable()) {

 

protocol.handleAccept(key);

 

}

 

/*if(!key.isConnectable()){

System.out.println("cancel.......");

key.cancel();

}*/

 

System.out.println("isReadable: "+key.isReadable());

if (key.isReadable()) {

 

protocol.handleRead(key);

 

}

 

// System.out.println("isWritable: "+key.isWritable()

// +";isValid="+key.isValid());

 

try{

if (key.isWritable() && key.isValid()) {

 

protocol.handleWrite(key);

 

}

 

}catch(Exception e){

e.printStackTrace ();

key.cancel();

if(null != key.channel() && key.channel().isOpen()){

key.channel();

}

}

// Since the select() operation just adds elements to the set of keys associated with the Selector

 

// So without removing every processed key,

 

// it will remain in the collection the next time the select() method is called

 

// And there may be useless operations to call it.

 

keyIter.remove();

 

}

 

}

 

}

 

}

 

 

package nio.study.serverclient;

 

import java.io.IOException;

 

import java.nio.channels.SelectionKey;

 

 

 

public interface Protocol {

 

    public void handleAccept(SelectionKey key) throws IOException;

 

    public void handleRead(SelectionKey key) throws IOException;

 

    public void handleWrite(SelectionKey key) throws IOException;

 

}

 

package nio.study.serverclient;

 

import java.io.IOException;

import java.nio.ByteBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

 

public class EchoProtocol implements Protocol {

 

private int bufsize;// buffer size created for each client channel

 

public EchoProtocol(int bufsize) {

 

this.bufsize = bufsize;

 

}

 

public void handleAccept(SelectionKey key) throws IOException {

 

// The channel() method returns the Channel created during registration, which is a ServerSocketChannel,

 

// Because this is the only channel we've registered that supports the accept operation,

 

// The accept() method returns a SocketChannel instance for the incoming connection.

 

SocketChannel channel = ((ServerSocketChannel) key.channel()).accept();

 

// Blocking channels cannot be registered here, they must be non-blocking

 

channel.configureBlocking(false);

 

// The corresponding Selector can be obtained through the selector() method of the SelectionKey class.

 

// We create a new ByteBuffer instance with the specified size,

 

// and pass it as a parameter to the register() method. It will be attached as an attachment, as returned by the register() method

 

// Associated with the SelectionKey instance.

channel.register(key.selector(), SelectionKey.OP_READ, ByteBuffer

 

.allocateDirect(bufsize));

 

}

 

public void handleRead(SelectionKey key) throws IOException {

 

// According to its support for data read operations, this is a SocketChannel.

 

SocketChannel channel = (SocketChannel) key.channel();

 

// After the connection is established, a ByteBuffer attachment is added to the SelectionKey instance, and the content of this attachment will be

 

// Will be used when sending, attachments are always attached to this long connection

 

ByteBuffer buf = (ByteBuffer) key.attachment();

 

long bytesRead = channel.read(buf);

// System.out.println("data::"+ new

// String (buf.array (), 0, (int) bytesRead));

 

// If the read() method returns -1, it means that the underlying connection has been closed, and the channel needs to be closed at this time.

 

// When a channel is closed, the key associated with that channel is removed from the selector's various collections.

 

if (bytesRead == -1) {

 

channel.close();

 

} else if (bytesRead> 0) {

 

// Set the current limit of the buffer to position=0 for subsequent read operations on the buffer

buf.flip();

// Create a byte array based on the number of readable bytes in the buffer //buf.remaining() can read the length

byte[] bytes = new byte[buf.remaining()];

// Copy the buffer readable byte array to the newly created array

buf.get(bytes);

String expression = new String(bytes, "UTF-8");

System.out.println("Server received message: " + expression);

// Data processing

buf.clear();

// The readable operation of the channel is still preserved here, although there may be no space left in the buffer,

 

key.interestOps(SelectionKey.OP_WRITE);

 

}

 

}

 

public void handleWrite(SelectionKey key) throws IOException {

System.out.println("======write---");

// The ByteBuffer attached to the SelectionKey contains the data previously read from the channel.

// Read the client's data begin

//ByteBuffer buf = (ByteBuffer) key.attachment();

// This method is used to modify the internal state of the buffer to indicate where the write operation gets data from and how much data is left

// buf.flip();

 

//////// end

 

String back = "99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend";

back =back+back+back;

// encode the message as a byte array

byte[] bytes = back.getBytes();

// Create ByteBuffer based on array capacity

ByteBuffer buf2 = ByteBuffer.allocate(bytes.length);

buf2.clear();

// copy byte array to buffer

buf2.put(bytes);

// flip operation, start writing from the 0 position of the buffer

buf2.flip();

System.out.println("======write---2");

System.out.println("write:" + new String(bytes));

 

SocketChannel channel = (SocketChannel) key.channel();// 获取信道

if(buf2.hasRemaining()){

int len ​​=channel.write(buf2);//Write data to the channel

System.out.println("len:"+len);

 

}

if(null !=channel){

channel.close();

}

 

}

}

 

 

 

 

Client:

package nio.study.serverclient;

 

import java.net.InetSocketAddress;

 

import java.net.SocketException;

 

import java.nio.ByteBuffer;

 

import java.nio.channels.SocketChannel;

 

 

 

public class TCPEchoClientNoblocking {

 

 

public void send(int i) throws Exception{

 

String server = "127.0.0.1";

String mgs = i+"1234567890qwertyuiopasdfghjklmnbvcxzqwertyuiopasdfghjklmnbvcxz";

      byte[] data = mgs.getBytes();

 

      int servPort = 8888;

 

 

 

      SocketChannel clntChan =SocketChannel.open();

 

      clntChan.configureBlocking(false);

 

      //We "poll" the connection status by continuously calling the finishConnect() method before the connection is successfully established

 

       // Always return false. The print operation shows that the program can perform other tasks while waiting for the connection to be established

 

      if (!clntChan.connect(new InetSocketAddress(server,servPort))) {

 

          while (!clntChan.finishConnect()) 

 

          }

 

      }

 

      ByteBuffer writeBuf =ByteBuffer.wrap(data);

 

      ByteBuffer readBuf =ByteBuffer.allocate(data.length);

 

 

 

      int bytesRcvd = 0;

      int topNum =0;

     

      StringBuffer sb = new StringBuffer(64);

      while (bytesRcvd >= topNum) {

      if (writeBuf.hasRemaining()) {

      

      clntChan.write(writeBuf);

      

      }

      topNum = bytesRcvd;

      bytesRcvd = clntChan.read (readBuf);

      

    // 

      readBuf.flip();

      if(bytesRcvd >0){

       sb.append(new String(readBuf.array(), 0,readBuf.limit()));

      System.out.println("len;;;"+bytesRcvd +readBuf.hasRemaining());

      }

      readBuf.clear();

      }

      

      System.out.println("rev::"+sb.toString());

      

      clntChan.close();

 

}

 

    public static void main(String[] args) throws Exception {

    for(int i=0;i<300;i++){

    TCPEchoClientNoblocking t = new TCPEchoClientNoblocking();

   

    t.send(i);

    }

       

 

    }

 

}

 

 

log:

Server:

isAcceptable:true

isReadable: false

isAcceptable: false

isReadable: true

Server received message: 295ABCDEFGHIJKLMNOPQRSTUVWXYZ789564559

isAcceptable: false

isReadable: false

======write---

======write---2

write:99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend

len: 270

isAcceptable:true

isReadable: false

isAcceptable: false

isReadable: true

Server received message: 296ABCDEFGHIJKLMNOPQRSTUVWXYZ789564559

isAcceptable: false

isReadable: false

======write---

======write---2

write:99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend

len: 270

 

Client:

len ;;; 38true

len ;;; 38true

len ;;; 38true

len ;;; 38true

len ;;; 38true

len ;;; 38true

len ;;; 38true

len ;;; 4true

rev::99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend99999server1234567890123456789123456789=99999999999999999999=qwertyuioplkjhgfdsazxcvbnmend

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326615032&siteId=291194637