ServerSocketChannel
ServerSocketChannel是一个基于通道的socket监听器。它同我们所熟悉的 java.net.ServerSocket 执行相同的任务,不过它增加了通道语义,因此能够在非阻塞 模式下运行。
由于 ServerSocketChannel 没有 bind()方法,因此有必要取出对等的 socket 并使用 它来绑定到一个端口以开始监听连接。我们也是使用对等 ServerSocket 的 API 来根 据需要设置其他的 socket
package NIOTest.channel.socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
public class serverSocketChannelDemo {
public static void main(String[] args) throws IOException, InterruptedException {
//端口号
int port=4444;
//buffer缓冲区
ByteBuffer byteBuffer = ByteBuffer.wrap("啊啊".getBytes());
//ServerSocketChannel是一个基于socket监听器
ServerSocketChannel ssc = ServerSocketChannel.open();
//绑定通道对象,首先通过ServerSocketChannel.socket获取一个socket对象,然后绑定一个端口
// 开始监听连接.
ssc.socket().bind(new InetSocketAddress(port));
//设置非阻塞模式
ssc.configureBlocking(false);
while (true){
System.out.println("Waiting for connections");
//一直监听有没有新的连接传入
SocketChannel sc = ssc.accept();
if (sc==null){//没有连接的传入
Thread.sleep(1000);
System.out.println("没有连接传入 null");
}else {
Thread.sleep(1000);
System.out.println("connections:"+sc.socket().getRemoteSocketAddress());
byteBuffer.rewind();
sc.write(byteBuffer);
sc.close();
}
}
}
}
DatagramChannel 则模拟包 导向的无连接协议(如 UDP/IP)
package NIOTest.channel.socket;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class DatagramChannelDemo {
//发送的实现
@Test
public void sendDatagram() throws Exception {
//打开DatagramChannel
DatagramChannel datagramChannel = DatagramChannel.open();
InetSocketAddress senAddress = new InetSocketAddress("127.0.0.1",9999);
//发送
while (true){
ByteBuffer byteBuffer = ByteBuffer.wrap("张凯".getBytes(StandardCharsets.UTF_8));
datagramChannel.send(byteBuffer,senAddress);
System.out.println("发送");
Thread.sleep(1000);
}
}
//接受的实现
@Test
public void receiveDatagram() throws IOException {
//打开DatagramChannel
DatagramChannel receiveChannel = DatagramChannel.open();
InetSocketAddress receiveSocketAddress = new InetSocketAddress(9999);
//绑定
receiveChannel.bind(receiveSocketAddress);
//buffer
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
//接受
while (true){
byteBuffer.clear();
SocketAddress socket = receiveChannel.receive(byteBuffer);
byteBuffer.flip();
System.out.println(socket.toString());
System.out.println(StandardCharsets.UTF_8.decode(byteBuffer));
}
}
}
DatagramSocket实现假连接
UDP 不存在真正意义上的连接,这里的连接是向特定服务地址用 read 和 write 接收 发送数据包
package NIOTest.channel.socket;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.StandardCharsets;
public class DatagramChannelReadWriter {
public static void main(String[] args) {
}
@Test
public void buildConnect() throws Exception {
DatagramChannel datagramChannel = DatagramChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1", 9999);
datagramChannel.bind(new InetSocketAddress(9999));
ByteBuffer sendBuffer = ByteBuffer.wrap("欧文啊啊啊aaaa".getBytes(StandardCharsets.UTF_8));
ByteBuffer receive = ByteBuffer.allocate(1024);
datagramChannel.send(sendBuffer,inetSocketAddress);
receive.clear();
SocketAddress receive1 = datagramChannel.receive(receive);
receive.flip();
System.out.println(receive1.toString());
System.out.println(StandardCharsets.UTF_8.decode(receive));
datagramChannel.close();
}
}