import javax.swing.text.html.HTMLDocument;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;
public class Test1{
public static void main(String[] args) throws IOException{
InetAddress localHost=InetAddress.getLocalHost();
System.out.println(localHost);
ServerSocketChannel serverSocketChannel=ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(3000));
serverSocketChannel.configureBlocking(false);
Selector selector=Selector.open();
ServerSocketChannel serverSocketChannel0=ServerSocketChannel.open();
serverSocketChannel0.bind(new InetSocketAddress(3001));
serverSocketChannel0.configureBlocking(false);
ServerSocketChannel serverSocketChannel1=ServerSocketChannel.open();
serverSocketChannel1.bind(new InetSocketAddress(3002));
serverSocketChannel1.configureBlocking(false);
SelectionKey selectionKey0=serverSocketChannel0.register(selector,SelectionKey.OP_ACCEPT);
SelectionKey selectionKey1=serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
SelectionKey selectionKey2=serverSocketChannel1.register(selector,SelectionKey.OP_ACCEPT);
while(true){
selector.select(); //选择一组键 此处为阻塞,程序平时停留在这里
Set<SelectionKey> set=selector.selectedKeys(); //返回此选择器的selected-key集
Iterator iterator= set.iterator();
while(iterator.hasNext()){ //可以读多次
SelectionKey key= (SelectionKey) iterator.next(); //
if(key.isAcceptable()){
ServerSocketChannel channel= (ServerSocketChannel) key.channel();
SocketChannel socketChannel=channel.accept();
Socket sc=socketChannel.socket();
InputStream is=sc.getInputStream();
byte[] b=new byte[100];
is.read(b);
System.out.println(new String(b));
OutputStream os = sc.getOutputStream();
os.write("fwq:hello".getBytes(StandardCharsets.UTF_8));
iterator.remove(); //删除已用的key,这句特别重要,一定要加,否则要报错
socketChannel.close();
sc.close();
}
}
}
}
}
用nio读取文件,特别注意buffer.clear().
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
public class Kf1 {
public static void main(String[] args) throws IOException, InterruptedException {
FileChannel fileChannel=FileChannel.open(Path.of("/Users/wangzhong/St.java"));
ByteBuffer buffer=ByteBuffer.allocate(10);
String s="";
int t=fileChannel.read(buffer); // 读10个字节的文件内容
System.out.println(t); //t=10
while (t!=-1) { //-1代表已读完
s=s+new String(buffer.array()); //10个字节的buffer内容累加
buffer.clear(); //这句特别重要,清空buffer
t = fileChannel.read(buffer); //再读10字节
}
System.out.println(s);
}
}
如果buffer长度取值很大,文件数据小,最后生成的s就会带有空格符号,所以s要trip() 一下。一直还不是很清楚,为什么搞一个这么复杂的bytefuffer,可能主要把它用在多线程上的原因吧,因为它是同步的。所以单线路就不要采用bytebuffer这种方法了。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class Kf1 {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel serverSocketChannel1 = ServerSocketChannel.open();
serverSocketChannel1.bind(new InetSocketAddress(3000));
serverSocketChannel1.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel1.register(selector, SelectionKey.OP_ACCEPT);
SocketChannel socketChannel = null;
while (true) {
selector.select(); //选择一组键 此处为阻塞,程序平时停留在这里
Set<SelectionKey> selectionKeysSet = selector.selectedKeys(); //返回此选择器的selected-key集
Iterator<SelectionKey> iterator = selectionKeysSet.iterator();
while (iterator.hasNext()) { //可以读多次
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
socketChannel = channel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isWritable()) {
byte[] writeDate = "w".getBytes();
ByteBuffer buffer = ByteBuffer.wrap(writeDate);
socketChannel.write(buffer);
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
// int port=sc.getLocalPort();
ByteBuffer buffer=ByteBuffer.allocate(100000);
int readLengh=socketChannel.read(buffer);
String newString=new String(buffer.array(),0,readLengh);
if(!newString.equals("*")) {
System.out.println(newString);
}
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_WRITE);
}
Thread.sleep(100);
iterator.remove();
}
}
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class Test12 {
static String s="*";
public static void main(String[] args) throws IOException, InterruptedException {
Scan t=new Scan();
t.start();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("192.168.1.20", 3000));
boolean isRun=true;
while(isRun==true) {
selector.select();
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeySet.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isConnectable()) {
if (socketChannel.isConnectionPending()) {
while ((!socketChannel.finishConnect())) {
System.out.println("2");
}
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_WRITE);
}
}
if (key.isReadable()) {
// int port=sc.getLocalPort();
ByteBuffer buffer=ByteBuffer.allocate(100000);
int readLengh=socketChannel.read(buffer);
String newString=new String(buffer.array(),0,readLengh);
if(!newString.equals("w")) {
System.out.println(newString);
}
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_WRITE);
}
if (key.isWritable()) {
byte[] writeDate =(Test12.s).getBytes();
ByteBuffer buffer1 = ByteBuffer.wrap(writeDate);
socketChannel.write(buffer1);
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ);
Test12.s="*";
}
Thread.sleep(100);
iterator.remove();
}
}
}
}
class Scan extends Thread{
public synchronized void run(){
while(true) {
Scanner sc = new Scanner(System.in);
String s1 = sc.nextLine();
Test12.s = s1;
}
}
}
监控两端口服务器,注册了两个选择器,分别对应两个端口
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class Test1 {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocketChannel serverSocketChannel1 = ServerSocketChannel.open();
serverSocketChannel1.bind(new InetSocketAddress(3000));
serverSocketChannel1.configureBlocking(false);
ServerSocketChannel serverSocketChannel2 = ServerSocketChannel.open();
serverSocketChannel2.bind(new InetSocketAddress(3001));
serverSocketChannel2.configureBlocking(false);
Selector selector1 = Selector.open();
serverSocketChannel1.register(selector1, SelectionKey.OP_ACCEPT);
SocketChannel socketChannel1 = null;
Selector selector2 = Selector.open();
serverSocketChannel2.register(selector2, SelectionKey.OP_ACCEPT);
SocketChannel socketChannel2 = null;
Fw1 t1=new Fw1(selector1,socketChannel1);
Fw2 t2=new Fw2(selector2,socketChannel2);
t1.start();
t2.start();
}
}
class Fw1 extends Thread {
Selector selector;
SocketChannel socketChannel;
Fw1(Selector selector, SocketChannel socketChannel) {
this.selector = selector;
this.socketChannel = socketChannel;
}
public void run() {
while (true) {
try {
selector.select(); //选择一组键 此处为阻塞,程序平时停留在这里
Set<SelectionKey> selectionKeysSet = selector.selectedKeys(); //返回此选择器的selected-key集
Iterator<SelectionKey> iterator = selectionKeysSet.iterator();
while (iterator.hasNext()) { //可以读多次
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
socketChannel = channel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
// int port=sc.getLocalPort();
ByteBuffer buffer = ByteBuffer.allocate(100000);
int readLengh = socketChannel.read(buffer);
String newString = new String(buffer.array(), 0, readLengh);
System.out.println(newString);
socketChannel.register(selector, SelectionKey.OP_WRITE);
}
if (key.isWritable()) {
byte[] writeDate = "Server1".getBytes();
ByteBuffer buffer = ByteBuffer.wrap(writeDate);
socketChannel.write(buffer);
socketChannel.register(selector, SelectionKey.OP_READ);
}
Thread.sleep(1000);
iterator.remove();
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class Fw2 extends Thread {
Selector selector;
SocketChannel socketChannel;
Fw2(Selector selector, SocketChannel socketChannel) {
this.selector = selector;
this.socketChannel = socketChannel;
}
public void run() {
while (true) {
try {
selector.select(); //选择一组键 此处为阻塞,程序平时停留在这里
Set<SelectionKey> selectionKeysSet = selector.selectedKeys(); //返回此选择器的selected-key集
Iterator<SelectionKey> iterator = selectionKeysSet.iterator();
while (iterator.hasNext()) { //可以读多次
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
socketChannel = channel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
}
if (key.isReadable()) {
// int port=sc.getLocalPort();
ByteBuffer buffer = ByteBuffer.allocate(100000);
int readLengh = socketChannel.read(buffer);
String newString = new String(buffer.array(), 0, readLengh);
System.out.println(newString);
socketChannel.register(selector, SelectionKey.OP_WRITE);
}
if (key.isWritable()) {
byte[] writeDate = "Server2".getBytes();
ByteBuffer buffer = ByteBuffer.wrap(writeDate);
socketChannel.write(buffer);
socketChannel.register(selector, SelectionKey.OP_READ);
}
Thread.sleep(1000);
iterator.remove();
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
客户端3000
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class Test11 {
public static void main(String[] args) throws IOException, InterruptedException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("192.168.43.61", 3000));
boolean isRun=true;
while(isRun==true) {
selector.select();
Set<SelectionKey> selectionKeySet = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeySet.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isConnectable()) {
if (socketChannel.isConnectionPending()) {
while ((!socketChannel.finishConnect())) {
System.out.println("2");
}
socketChannel.register(selector,SelectionKey.OP_WRITE);
}
}
if (key.isWritable()) {
byte[] writeDate ="client1".getBytes(StandardCharsets.UTF_8);
ByteBuffer buffer1 = ByteBuffer.wrap(writeDate);
socketChannel.write(buffer1);
socketChannel.register(selector,SelectionKey.OP_READ);
}
if (key.isReadable()) {
// int port=sc.getLocalPort();
ByteBuffer buffer=ByteBuffer.allocate(100000);
int readLengh=socketChannel.read(buffer);
String newString=new String(buffer.array(),0,readLengh);
System.out.println(newString);
socketChannel.register(selector,SelectionKey.OP_WRITE);
}
Thread.sleep(2000);
iterator.remove();
}
}
}
}
//========================================================================duplicate(): 复制缓冲区 利用duplicate 可以一个线程写入,同时一个线程读取
下面的程序一边写入1-100的数据,另一个线程读取
import java.nio.ByteBuffer;
public class Test {
static ByteBuffer byteBuffer=ByteBuffer.allocateDirect(90000000);
static ByteBuffer byteBuffer1=byteBuffer.duplicate();
public static void main(String[] args) throws InterruptedException {
Rd rd=new Rd();
rd.start();
for(int t=1;t<=100;t++){
byteBuffer.put((byte)t);
Thread.sleep(1000);
System.out.println("b="+t);
}
}
}
class Rd extends Thread{
public synchronized void run(){
int n=0;
while(n<=100) {
for ( n = 1; n <= 100; n++) {
while(Test.byteBuffer1.get(n)==0){
;
}
System.out.println("b1="+Test.byteBuffer1.get(n));
}
}
}
}