带有Java NIO套接字的CastException

带有Java NIO套接字的CastException,java,class,sockets,nio,Java,Class,Sockets,Nio,我一直在学习ProJava7NIO.2这本书,以便更好地理解NIO包,并希望编写一些与网络相关的代码,以便更好地理解netty在后台的工作方式。总的错误是有道理的,但我无法理解为什么会抛出错误 java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel 我做的第一件事是确保我的代码没有从sun包导入任何东西,并且所有东西实际上

我一直在学习ProJava7NIO.2这本书,以便更好地理解NIO包,并希望编写一些与网络相关的代码,以便更好地理解netty在后台的工作方式。总的错误是有道理的,但我无法理解为什么会抛出错误

java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
我做的第一件事是确保我的代码没有从sun包导入任何东西,并且所有东西实际上都在使用java.nio包。一切似乎都很顺利

当我尝试将客户机连接到服务器时,会抛出此错误,但真正困扰我的是,它试图将cast键入ServerSocketChannel,而不仅仅是SocketChannel,这让我认为服务器很混乱

我确实为下面的代码墙提前表示歉意,但由于每个人都要求我发布一个运行示例,我计划这样做。这是三个小类文件

TcpProcessor.java

Server.java

调用TcpProcessorprocessIncomingConnection时发生错误,这将调用新连接实例的创建。抛出这个错误的那行代码直接引用了这本书,我已经查看了其他几个NIO服务器,这行代码完全相同,但大多数都没有命名

this.clientSocket = (SocketChannel)selectionKey.channel();
如果您有任何帮助,我们将不胜感激,为您提供完整的控制台输出:

Server has started and is waiting for connections...
Incoming connection from /127.0.0.1:53221
Exception in thread "Thread-0" java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
    at net.ogserver.proto.connections.Connection.<init>(Connection.java:17)
    at net.ogserver.proto.tcp.TcpProcessor.processIncomingConnection(TcpProcessor.java:60)
    at net.ogserver.proto.tcp.TcpProcessor.run(TcpProcessor.java:37)
    at java.lang.Thread.run(Thread.java:745)

我可能应该补充一点,selectionkey.channel的类型转换socketchannel的实现直接来自JavaDocs-

sun.nio.ch.*类似乎包含java.nio.*包中接口的一些实现;到不同包的交叉发生在您正在使用的实现类中。那里没有什么神秘的东西

通过查看sun.nio.ch.ServerSocketChannel的源代码,我发现它实现了java.nio.channels.ServerSocketChannel,而不是java.nio.channels.SocketChannel。这是一个通道实现,而不是套接字实现。java.nio.channels中的ServerSocketChannel和SocketChannel都扩展了AbstractSelectableChannel,但它们是继承层次结构中的同级,而不是祖先/后代


希望能有所帮助。

您将错误的选择键传递到新连接。。。。您正在传递服务器套接字的密钥。您应该传递的密钥是接受的套接字的密钥,它是下一行socketChannel.register的结果。

查看sun.nio.ch.serversocketchannelml源代码,它似乎扩展了java.nio.channels.ServerSocketChannel并实现了sun.nio.ch.selchinpl,但这似乎与java.nio.channels没有关系。SocketChannel@hammerfest-最奇怪、最令人难以置信的问题是,只有在本地连接客户端时才会发生这种情况。此客户端与服务器位于同一台计算机上问题在于,当我建立本地连接时,ServerSocketChannel是从SelectionKey提交的,但是,如果我通过服务器未运行的网络与计算机建立远程连接,它会像应该的那样注册为SocketChannel,并继续服务器/客户端通信过程。转换到AbstractSelectableChannel是否会满足您的要求?我不熟悉java.nio socket类,所以我只是在这里摸黑。关键是你说的两个类最终都可以扩展这个类。恐怕我无法解释为什么这两个类都有抽象类中没有定义的常用方法bind、socket和accept——在我看来,这将是人们想要的。@arcy不,不会的。他需要用它来读和写。他们都没有接受的方法。谢谢,我想知道我哪里出了问题。这使一切都运转良好。
package net.ogserver.proto;

import net.ogserver.proto.tcp.TcpProcessor;


public class Server {

    private Thread tcpProcessor;

    public Server(int port) {
        TcpProcessor.tcpPort = port;
        tcpProcessor = new Thread(new TcpProcessor());
        tcpProcessor.start();
    }

    public static void main(String[] args) {
        new Server(5055);
    }
}
this.clientSocket = (SocketChannel)selectionKey.channel();
Server has started and is waiting for connections...
Incoming connection from /127.0.0.1:53221
Exception in thread "Thread-0" java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
    at net.ogserver.proto.connections.Connection.<init>(Connection.java:17)
    at net.ogserver.proto.tcp.TcpProcessor.processIncomingConnection(TcpProcessor.java:60)
    at net.ogserver.proto.tcp.TcpProcessor.run(TcpProcessor.java:37)
    at java.lang.Thread.run(Thread.java:745)