在网络编程的过中,使用到通道中的socketChannel和serverSocketChannel这两个类,其中socketChannel类可以读写TCP Socket ,数据必须编码到ByteBuffer对象中来完成读写。
1 创建socketChannel对象
方法一
SocketAddress address=new InetSocketAddress("wwww.baidu.com",1233);
SocketChannel channel=SocketChannel.open(address);
方法二
SocketAddress address=new InetSocketAddress("wwww.baidu.com",1233);
SocketChannel channel=SocketChannel.open();
channel.configureBlocking(false); //无阻塞方式打开通道
channel.connect(address);
2 读取
使用方法read(ByteBuffer dst)读取对象中的数据
注意:
如果是通道是阻塞的该方法在流末尾会返回一个-1 ,如果通道是非阻塞的该方法会返回0
3 写入
write(ByteBuffer src)
4 关闭
close() 使用isope()检查是否关闭
serverSocketChannel
serverSocketChannel只有一个目的:接受入站连接,无法读取,写入或者连接serverSocketChannel,他支持的唯一操作是接受一个新的入站连接
创建一个socket通道
ServerSocketChannel serverChannel=ServerSocketChannel.open();
SocketAddress address=new InetSocketAddress(80);
serverChannel.bind(address);
接受连接
SocketChannel channle=serverChannel.accept();
连接分为阻塞连接和非阻塞连接,在阻塞的模式下,accept()方法等待入站连接,在接连建立之前,线程无法进行任何操作,这种策略适用于立即响应每一个请求的简单服务器,阻塞模式是默认模式。
在非阻塞模式情况下,在没有建立连接之前,accept()返回的一个null,非阻塞模式更适合于需要为每一个连接完成大量工作的服务器,这样可以进行并行的处理多个请求,使用configureBlocking(false)设置。
代码如下
服务器端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
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 ServerSocketChannelTest {
public static void main(String[] args) throws IOException {
ServerSocketChannelTest server=new ServerSocketChannelTest();
server.readMessage();
}
public void readMessage(){
System.out.println("进入服务端");
try {
//使用静态工厂的模式获取ServerSocketChannel
ServerSocketChannel serverChannel=ServerSocketChannel.open();
Selector selector=Selector.open();
// 绑定接口
serverChannel.bind(new InetSocketAddress(1233));
while(true){
//指定服务器中是否阻塞
serverChannel.configureBlocking(false);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
selector.select(20000);
Set<SelectionKey> readKeys=selector.selectedKeys();
Iterator<SelectionKey> iterable=readKeys.iterator();
while(iterable.hasNext()){
SelectionKey key=iterable.next();
if(key.isAcceptable()){
handleAccept(key);
}else if(key.isWritable()){
handleWrite(key);
}else if(key.isReadable()){
handleRead(key);
}
iterable.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void handleRead(SelectionKey key){
SocketChannel sc=(SocketChannel) key.channel();
ByteBuffer buf=(ByteBuffer) key.attachment();
try {
long bytesRead=sc.read(buf);
while(bytesRead>0){
buf.flip();
while(buf.hasRemaining()){
System.out.print((char)buf.get());
}
System.out.println();
buf.clear();
bytesRead=sc.read(buf);
}
if(bytesRead==-1){
sc.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void handleAccept(SelectionKey key){
ServerSocketChannel ssChannel=(ServerSocketChannel) key.channel();
try {
SocketChannel channle=ssChannel.accept();
channle.configureBlocking(false);
channle.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocateDirect(1000));
} catch (IOException e) {
e.printStackTrace();
}
}
public void handleWrite(SelectionKey key){
ByteBuffer buf=(ByteBuffer) key.attachment();
buf.flip();
SocketChannel channle=(SocketChannel) key.channel();
while(buf.hasRemaining()){
try {
channle.write(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
buf.compact();
}
}
客户端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class SocketChannlTest {
public static void main(String[] args) {
for(int i=0;i<10;i++){
SocketChannel client;
try {
client = SocketChannel.open();
client.configureBlocking(false);
new Get(client).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class Get extends Thread{
private SocketChannel connection;
Get(SocketChannel connection){
this.connection=connection;
}
public void run(){
ByteBuffer buffer=ByteBuffer.allocate(100);
SocketAddress adress=new InetSocketAddress("localhost",1233);
try {
connection.connect(adress);
if(connection.finishConnect()){
int i=0;
while(true){
try {
TimeUnit.SECONDS.sleep(1);
String info="我是+"+i+++"th client";
buffer.clear();
buffer.put(info.getBytes());
buffer.flip();
while(buffer.hasRemaining()){
System.out.println(buffer.toString());
connection.write(buffer);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(connection!=null)
{
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}