TCP/IP 无阻塞 Socket

package com.io;

import java.net.InetSocketAddress;
import java.net.ServerSocket;
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;

public class NewSocketServer {
public static void main(String[] args) throws Exception {
int port = 9527;
//打开选择器
Selector selector = Selector.open();
//打开服务器套接字通道
ServerSocketChannel ssc = ServerSocketChannel.open();
//检索与此通道关联的服务器套接字。
ServerSocket serverSocket = ssc.socket();
//将 ServerSocket 绑定到特定地址(IP 地址和端口号)
serverSocket.bind(new InetSocketAddress(port));
System.out.println("Server listen on port: " + port);
//调整此通道的阻塞模式。
ssc.configureBlocking(false);
//向给定的选择器注册此通道,返回一个选择键。SelectionKey.OP_ACCEPT--用于套接字接受操作的操作集位
ssc.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
//timeout - 如果为正,则在等待某个通道准备就绪时最多阻塞 timeout 毫秒;如果为零,则无限期地阻塞;必须为非负数
int nKeys = selector.select(1000);
if (nKeys > 0) {
for (SelectionKey key : selector.selectedKeys()) {
//测试此键的通道是否已准备好接受新的套接字连接--如果此键的通道不支持套接字接受操作,则此方法始终返回 false。
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key
.channel();
SocketChannel sc = server.accept();
if (sc == null) {
continue;
}
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
//分配一个新的字节缓冲区。
ByteBuffer buffer = ByteBuffer.allocate(1024);
SocketChannel sc = (SocketChannel) key.channel();
int readBytes = 0;
String message = null;
try {
int ret;
try {
while ((ret = sc.read(buffer)) > 0) {
readBytes += ret;
}
} catch (Exception e) {
readBytes = 0;
// IGNORE
} finally {
//反转此缓冲区。首先对当前位置设置限制,然后将该位置设置为零
buffer.flip();
}
if (readBytes > 0) {
message = Charset.forName("UTF-8").decode(
buffer).toString();
buffer = null;
}
} finally {
if (buffer != null) {
buffer.clear();
}
}
if (readBytes > 0) {
System.out.println("Message from client: "
+ message);
if ("quit".equalsIgnoreCase(message.trim())) {
sc.close();
selector.close();
System.out.println("Server has been shutdown!");
System.exit(0);
}
String outMessage = "Server response:" + message;
sc.write(Charset.forName("UTF-8")
.encode(outMessage));
}
}
}
selector.selectedKeys().clear();
}
}
}

}



package com.io;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

public class NewSokectClient {
public static void main(String[] args) throws Exception {
int port = 9527;
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
SocketAddress target = new InetSocketAddress("127.0.0.1", port);
channel.connect(target);
Selector selector = Selector.open();
//用于套接字连接操作的操作集位。
channel.register(selector, SelectionKey.OP_CONNECT);
BufferedReader systemIn = new BufferedReader(new InputStreamReader(
System.in));
while (true) {
if (channel.isConnected()) {
String command = systemIn.readLine();
channel.write(Charset.forName("UTF-8").encode(command));
if (command == null || "quit".equalsIgnoreCase(command.trim())) {
systemIn.close();
channel.close();
selector.close();
System.out.println("Client quit!");
System.exit(0);
}
}
int nKeys = selector.select(1000);
if (nKeys > 0) {
for (SelectionKey key : selector.selectedKeys()) {
if (key.isConnectable()) {
SocketChannel sc = (SocketChannel) key.channel();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
sc.finishConnect();
} else if (key.isReadable()) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
SocketChannel sc = (SocketChannel) key.channel();
int readBytes = 0;
try {
int ret = 0;
try {
while ((ret = sc.read(buffer)) > 0) {
readBytes += ret;
}
} finally {
buffer.flip();
}
if (readBytes > 0) {
System.out.println(Charset.forName("UTF-8")
.decode(buffer).toString());
buffer = null;
}
} finally {
if (buffer != null) {
buffer.clear();
}
}
}
}
selector.selectedKeys().clear();
}
}

}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值