用于传入连接的Java NIO选择器和用于传入消息的选择器
我正在尝试使用NIO构建一个高效的套接字TCP/IP服务器 我有一个主线程,它接受连接,然后将它添加到另一个线程,该线程应该等待来自客户端的消息,然后读取它 当我只使用一个线程和一个选择器来执行所有操作时,效果非常好,但当我尝试使用两个线程和两个选择器时,传入的连接accept正常工作,但读数不正常,我认为这是因为我的选择器阻塞了线程,因此他不知道我已经注册了一个新的SocketChannel 这是我的主线:用于传入连接的Java NIO选择器和用于传入消息的选择器,java,sockets,nio,Java,Sockets,Nio,我正在尝试使用NIO构建一个高效的套接字TCP/IP服务器 我有一个主线程,它接受连接,然后将它添加到另一个线程,该线程应该等待来自客户端的消息,然后读取它 当我只使用一个线程和一个选择器来执行所有操作时,效果非常好,但当我尝试使用两个线程和两个选择器时,传入的连接accept正常工作,但读数不正常,我认为这是因为我的选择器阻塞了线程,因此他不知道我已经注册了一个新的SocketChannel 这是我的主线: public static void main(String[] args) {
public static void main(String[] args) {
try {
System.out.println("Who's Around Server Started!");
Selector connectionsSelector = null;
ServerSocketChannel server = null;
String host = "localhost";
int port = 80;
LiveConnectionsManager liveConnectionsManager =
new LiveConnectionsManager();
liveConnectionsManager.start();
connectionsSelector = Selector.open();
server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(host,port));
server.configureBlocking(false);
server.register(connectionsSelector, SelectionKey.OP_ACCEPT);
while (true) {
connectionsSelector.select();
Iterator<SelectionKey> iterator =
connectionsSelector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey incomingConnection = iterator.next();
iterator.remove();
if( incomingConnection.isConnectable()) {
((SocketChannel)incomingConnection.channel()).finishConnect();
}
if( incomingConnection.isAcceptable()){
acceptConnection(server.accept(), liveConnectionsManager);
}
}
}
} catch (Throwable e) {
throw new RuntimeException("Server failure: " + e.getMessage());
}
}
private static void acceptConnection(
SocketChannel acceptedConnection,
LiveConnectionsManager liveConnectionsManager ) throws IOException
{
acceptedConnection.configureBlocking(false);
acceptedConnection.socket().setTcpNoDelay(true);
System.out.println(
"New connection from: " + acceptedConnection.socket().getInetAddress());
liveConnectionsManager.addLiveConnection(acceptedConnection);
}
publicstaticvoidmain(字符串[]args){
试一试{
System.out.println(“谁在服务器旁启动了!”);
选择器连接Selector=null;
serversocketchannelserver=null;
String host=“localhost”;
int端口=80;
LiveConnectionManager LiveConnectionManager=
新建LiveConnectionsManager();
liveConnectionsManager.start();
connectionsSelector=Selector.open();
server=ServerSocketChannel.open();
server.socket().bind(新的InetSocketAddress(主机、端口));
server.configureBlocking(false);
注册(ConnectionSelector,SelectionKey.OP_ACCEPT);
while(true){
connectionsSelector.select();
迭代器迭代器=
ConnectionSelector.selectedKeys().iterator();
while(iterator.hasNext()){
SelectionKey incomingConnection=iterator.next();
iterator.remove();
if(incomingConnection.isConnectable()){
((SocketChannel)incomingConnection.channel()).finishConnect();
}
if(incomingConnection.isAcceptable()){
acceptConnection(server.accept(),liveConnectionsManager);
}
}
}
}捕获(可丢弃的e){
抛出新的RuntimeException(“服务器故障:+e.getMessage());
}
}
专用静态连接(
SocketChannel接受连接,
LiveConnectionManager(LiveConnectionManager)引发IOException
{
acceptedConnection.configureBlocking(false);
acceptedConnection.socket().setTcpNoDelay(true);
System.out.println(
新连接来自:“+acceptedConnection.socket().getInetAddress());
liveConnectionsManager.addLiveConnection(acceptedConnection);
}
这是我的LiveConnectionsManager:
private Selector messagesSelector;
public LiveConnectionsManager(){
try {
messagesSelector = Selector.open();
} catch (IOException e) {
System.out.println("Couldn't run LiveConnectionsManager");
}
}
@Override
public void run() {
try {
System.out.println("LiveConnectionManager Started!");
while(true) {
messagesSelector.select();
Iterator<SelectionKey> iterator = messagesSelector.keys().iterator();
while (iterator.hasNext()){
SelectionKey newData = iterator.next();
iterator.remove();
if( newData.isReadable()){
readIncomingData(((SocketChannel)newData.channel()));
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void addLiveConnection( SocketChannel socketChannel )
throws ClosedChannelException
{
socketChannel.register(messagesSelector, SelectionKey.OP_READ);
}
专用选择器消息选择器;
公共LiveConnectionsManager(){
试一试{
messagesSelector=Selector.open();
}捕获(IOE异常){
System.out.println(“无法运行LiveConnectionManager”);
}
}
@凌驾
公开募捐{
试一试{
System.out.println(“LiveConnectionManager已启动!”);
虽然(正确){
messagesSelector.select();
迭代器迭代器=messagesSelector.keys().Iterator();
while(iterator.hasNext()){
SelectionKey newData=iterator.next();
iterator.remove();
if(newData.isReadable()){
readIncomingData(((SocketChannel)newData.channel());
}
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
public void addLiveConnection(SocketChannel SocketChannel)
抛出ClosedChannel异常
{
socketChannel.register(messages选择器,SelectionKey.OP_READ);
}
与其构建自己的NIO服务器,不如看一看。在一个线程中完成这一切。您的设计没有很大的优势,而且很难实现多线程NIO。