ServerSocketChannel和SocketChannel
服务端代码
import java.io.IOException;
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.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @program: smbTest
* @description:
* @author: hw
* @create: 2020-10-22 15:30
*/
public class NIOSServer implements Runnable {
private int port = 445;
private Charset cs = Charset.forName("gbk");
private ByteBuffer sBuffer = ByteBuffer.allocate(1024);
private ByteBuffer rBuffer = ByteBuffer.allocate(1024);
private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();
private Selector selector;
public NIOSServer(int port) {
this.port = port;
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
private void init() throws IOException {
// 创建ServerSocketChannel通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 设置为非阻塞模式
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
// 绑定监听端口
serverSocket.bind(new InetSocketAddress(port));
// 注册选择器,设置选择器选择的操作类型
selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("[SMB] SMB Server starting");
System.out.println("[SMB] Listening for connections on [SMB,TCP-SMB,ALL:" + port + "]");
System.out.println("[SMB] Waiting for new connection ...");
}
@Override
public void run() {
while (true) {
try {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
for (SelectionKey key : selectionKeys) {
handle(key);
}
selectionKeys.clear();
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
private void handle(SelectionKey selectionKey) throws IOException{
ServerSocketChannel server = null;
SocketChannel client = null;
String receiveText = null;
int count = 0;
if (selectionKey.isAcceptable()) {
// 通过选择器键获取服务器套接字通道
server = (ServerSocketChannel) selectionKey.channel();
// 通过accept()方法获取套接字通道连接
client = server.accept();
//判断client 是否为空
if (client != null) {
// 设置套接字通道为非阻塞模式
client.configureBlocking(false);
// 为套接字通道注册选择器,该选择器为服务器套接字通道的选择器,即选择到该SocketChannel的选择器
// 设置选择器关心请求为读操作,设置数据读取的缓冲器容量为处理器初始化时候的缓冲器容量
client.register(selector, SelectionKey.OP_READ);
System.out.println("[SMB] Connection from " + client.socket().getRemoteSocketAddress());
}
} else if (selectionKey.isReadable()) {
// 获取套接字通道
client = (SocketChannel) selectionKey.channel();
rBuffer.clear();
count = client.read(rBuffer);
if (count > 0) {
rBuffer.flip();
receiveText = String.valueOf(cs.decode(rBuffer).array());
System.out.println("[SMB] "+client.socket().getRemoteSocketAddress() + ":" + receiveText);
dispatch(client, receiveText);
client = (SocketChannel) selectionKey.channel();
client.register(selector, SelectionKey.OP_READ);
}
}
}
private void dispatch(SocketChannel client, String info) throws IOException {
Socket s = client.socket();
String name = "[" + s.getInetAddress().toString().substring(1) + ":" + Integer.toHexString(client.hashCode()) + "]";
if (!clientsMap.isEmpty()) {
for (Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()) {
SocketChannel temp = entry.getValue();
if (!client.equals(temp)) {
sBuffer.clear();
sBuffer.put((name + ":" + info).getBytes());
sBuffer.flip();
temp.write(sBuffer);
}
}
}
clientsMap.put(name, client);
}
public static void main(String[] args) {
NIOSServer server = new NIOSServer(1445);
new Thread(server).start();
NIOClient client = new NIOClient("192.168.120.67",1445);
new Thread(client).start();
NIOClient client2 = new NIOClient("192.168.120.67",1445);
new Thread(client2).start();
}
}
客户端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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.util.Date;
import java.util.Set;
/**
* @program: smbTest
* @description:
* @author: hw
* @create: 2020-10-22 16:01
*/
public class NIOClient implements Runnable{
private ByteBuffer sBuffer = ByteBuffer.allocate(1024);
private ByteBuffer rBuffer = ByteBuffer.allocate(1024);
private InetSocketAddress SERVER;
private Selector selector;
private SocketChannel client;
private String receiveText;
private String sendText;
private int count=0;
public NIOClient(String ip, int port){
SERVER = new InetSocketAddress(ip, port);
init();
}
public void init(){
try {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(SERVER);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true) {
selector.select();
Set<SelectionKey> keySet = selector.selectedKeys();
for(final SelectionKey key : keySet){
handle(key);
}
keySet.clear();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void handle(SelectionKey selectionKey) throws IOException{
if (selectionKey.isConnectable()) {
client = (SocketChannel) selectionKey.channel();
if (client.isConnectionPending()) {
client.finishConnect();
System.out.println("connect success !");
sBuffer.clear();
sBuffer.put((new Date()+" connected!").getBytes());
sBuffer.flip();
client.write(sBuffer);
//启动线程监听控制台输入并发送到客户端
new Thread(){
@Override
public void run() {
while(true){
try {
sBuffer.clear();
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input);
sendText = br.readLine();
sBuffer.put(sendText.getBytes());
sBuffer.flip();
client.write(sBuffer);
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}.start();
}
client.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
client = (SocketChannel) selectionKey.channel();
rBuffer.clear();
count=client.read(rBuffer);
if(count>0){
receiveText = new String( rBuffer.array(),0,count);
System.out.println(receiveText);
client = (SocketChannel) selectionKey.channel();
client.register(selector, SelectionKey.OP_READ);
}
}
}
public static void main(String args[]){
NIOClient client = new NIOClient("192.168.120.67",1445);
new Thread(client).start();
}
}
==========================================================================================
我希望每一篇文章的背后,都能看到自己对于技术、对于生活的态度。
我相信乔布斯说的,只有那些疯狂到认为自己可以改变世界的人才能真正地改变世界。面对压力,我可以挑灯夜战、不眠不休;面对困难,我愿意迎难而上、永不退缩。
其实我想说的是,我只是一个程序员,这就是我现在纯粹人生的全部。
==========================================================================================

浙公网安备 33010602011771号