ServerSocketChannel与serversocketjava

ServerSocketChannel与serversocketjava,java,sockets,serversocket,socketchannel,Java,Sockets,Serversocket,Socketchannel,我已经开始研究一个预先开发的Java应用程序,他们正在处理Java套接字。该项目的主要概念是在JavaSocket服务器上从客户机获取数据并对其进行处理 该项目是使用JavaNIOServerSocketchannel开发的 现在在这个场景中,我可以每秒从客户机获取大约70-80条记录。而如果我使用简单的JavaServerSocket(仅用于测试目的),输出将放大到大约800次 为什么这两者有这么大的区别? 我如何修改ServerSocketChannel以模仿ServerSocket 这是我

我已经开始研究一个预先开发的Java应用程序,他们正在处理Java套接字。该项目的主要概念是在JavaSocket服务器上从客户机获取数据并对其进行处理

该项目是使用JavaNIOServerSocketchannel开发的

现在在这个场景中,我可以每秒从客户机获取大约70-80条记录。而如果我使用简单的JavaServerSocket(仅用于测试目的),输出将放大到大约800次

为什么这两者有这么大的区别? 我如何修改ServerSocketChannel以模仿ServerSocket

这是我的主要处理部分

SocketChannel client = (SocketChannel) key.channel();
                        if (!key.isReadable()) {
                            key.cancel();
                            client.close();
                            continue;
                        }

                        int[] k = (int[]) key.attachment();

                        if (k[2] == 0) {
                                ByteBuffer lengthBuffer = ByteBuffer.allocate(2);

                                int bytesRead = -1;
                                if (!client.socket().isClosed() && key.isValid()) {
                                    bytesRead = client.read(lengthBuffer);
                                }

                                if (bytesRead == -1) {
                                    key.cancel();
                                    client.close();
                                    continue;
                                }
                                lengthBuffer.flip();
                                byte[] bytes = new byte[2];
                                lengthBuffer.get(bytes, 0, 2);
                                short length = DRMSDecoder.getShort(bytes);


                                k[0]++;
                                k[1] = length;
                                k[2] = 1;
                                key.attach(k);
                                lengthBuffer.clear();
                            } 
                            else {
                                try {

                                    int length = k[1];
                                    ByteBuffer dataBuffer = ByteBuffer.allocate(length);
                                    dataBuffer.clear();
                                    System.gc();

                                    int bytesRead = -1;
                                    if (!client.socket().isClosed() && key.isValid()) {
                                        bytesRead = client.read(dataBuffer);
                                    }

                                    if (bytesRead == -1) {
                                        key.cancel();
                                        client.close();
                                        continue;
                                    }

                                    dataBuffer.flip();

                                    Hashtable<String, Object> request = decoder.decode(dataBuffer);
                                    short call_type = (Short) request.get("Call Type");

                                    if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 78 || ((Short) request.get("Call Type")) == 80)) {


                                    } else if (request.get("Call Type") != null && (((Short) request.get("Call Type")) == 79)) {
                                        key.cancel();
                                        client.close();

                                    } 
                                        String message = (String) request.get("Buffer");

                                        handleMessage(message);

                                    }
                                    k[0]++;
                                    k[2] = 0;
                                    key.attach(k);
                                    lastMessageProcessed++;

                                    dataBuffer.clear();

                                } catch (Exception e) {
//                                    System.out.println(e);
                                }
                            }
SocketChannel客户端=(SocketChannel)key.channel();
如果(!key.isReadable()){
键。取消();
client.close();
继续;
}
int[]k=(int[])键。附件();
if(k[2]==0){
ByteBuffer lengthBuffer=ByteBuffer.allocate(2);
int字节读取=-1;
如果(!client.socket().isClosed()&&key.isValid()){
bytesRead=client.read(lengthBuffer);
}
如果(字节读==-1){
键。取消();
client.close();
继续;
}
lengthBuffer.flip();
字节[]字节=新字节[2];
lengthBuffer.get(字节,0,2);
短长度=DRMSDecoder.getShort(字节);
k[0]++;
k[1]=长度;
k[2]=1;
键。附加(k);
lengthBuffer.clear();
} 
否则{
试一试{
int-length=k[1];
ByteBuffer dataBuffer=ByteBuffer.allocate(长度);
dataBuffer.clear();
gc();
int字节读取=-1;
如果(!client.socket().isClosed()&&key.isValid()){
bytesRead=client.read(dataBuffer);
}
如果(字节读==-1){
键。取消();
client.close();
继续;
}
dataBuffer.flip();
哈希表请求=解码器.decode(数据缓冲);
short call_type=(short)request.get(“call type”);
if(request.get(“调用类型”)!=null&((短)request.get(“调用类型”))==78(短)request.get(“调用类型”)==80)){
}else if(request.get(“Call Type”)!=null&((Short)request.get(“Call Type”)==79)){
键。取消();
client.close();
} 
字符串消息=(字符串)请求.get(“缓冲区”);
handleMessage(消息);
}
k[0]++;
k[2]=0;
键。附加(k);
lastMessageProcessed++;
dataBuffer.clear();
}捕获(例外e){
//系统输出打印ln(e);
}
}

区别在于阻塞I/O与非阻塞I/O


参考:

但是我已经在做这个服务器了。配置阻塞(false);client.configureBlocking(false);这两个例子都是阻塞的。NIO的非阻塞通常要快一点,但在这种情况下,NIO要慢一点-1@JayVyasNIO在默认情况下是阻塞的。我写了一篇关于在Java中使用IO和NIO的最快到最慢的方法的文章。我能想到的最慢的方法是每次创建一个新的连接,但对于一个客户端,仍然是3500条消息/秒。我怀疑您的主要延迟不在网络层。您可以做很多事情来提高代码的效率,但我怀疑这能否解释您所看到的缓慢。您是否尝试过使用JMC评测应用程序?我将首先删除创建新对象的任何内容:PBTW我的文章链接到我使用的代码。我没有使用选择器,尽管它们不应该使代码慢很多Peter Lawrey谢谢,我会试试你的解决方案