Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 客户端的传统IO和服务器的NIO,如果客户端在同一个套接字中发送多条消息,如何获取特定消息?_Java_Sockets_Nio_Apache Mina - Fatal编程技术网

Java 客户端的传统IO和服务器的NIO,如果客户端在同一个套接字中发送多条消息,如何获取特定消息?

Java 客户端的传统IO和服务器的NIO,如果客户端在同一个套接字中发送多条消息,如何获取特定消息?,java,sockets,nio,apache-mina,Java,Sockets,Nio,Apache Mina,我在服务器端使用ApacheMina。我有一个客户是用传统IO写的。下面是将数据发送到服务器的客户端代码 class SomeClass extends Thread { Socket socket; //Constructor SomeClass() { Socket socket = ... } public void run() { while (j++ & lt; 10)

我在服务器端使用ApacheMina。我有一个客户是用传统IO写的。下面是将数据发送到服务器的客户端代码

class SomeClass extends Thread
{
    Socket socket;

    //Constructor
    SomeClass()
    {
        Socket socket = ...
    }

    public void run()
    {
        while (j++ & lt; 10)
        {
            System.out.println("CLIENT[" + clientNo + "] Send Message =>" + requests[clientNo][j]);
            OutputStream oStrm = socket.getOutputStream();
            byte[] byteSendBuffer = (requests[clientNo][j]).getBytes();
            oStrm.write(byteSendBuffer);
            oStrm.flush();
        }
    }
}
上面的线程运行了20次。因此,创建了20个套接字。在1个套接字中,许多消息被发送。通过使用IO套接字类编写的服务器,我能够完美地检索数据

问题出在使用缓冲区的基于ApacheMina的服务器上!我无法获得个人消息

如何获取单个消息(鉴于我无法在客户端中更改任何内容,并且单个消息的长度未知)

服务器端代码
套接字创建

公共静态void main(字符串[]args)引发IOException,SQLException{ System.out.println(Charset.defaultCharset().name()); IoAcceptor acceptor=新的NioSocketAcceptor(); ProtocolCodecFilter(charset.newEncoder(),charset.newDecoder()); acceptor.setHandler(新的TimeServerHandler()); acceptor.getSessionConfig().setReadBufferSize(64); acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,10); acceptor.bind(新的InetSocketAddress(PORT)); } 处理程序代码

public void messageReceived(IoSession会话,对象消息)引发异常{ AbstractIoBuffer bf=(AbstractIoBuffer)消息; Charset Charset=Charset.forName(“UTF-8”); CharsetDecoder=charset.newDecoder(); String outString=bf.getString(解码器); }
MINA实际上是一个非常复杂的框架,可以优雅地解决您的问题。它的基本概念是一个过滤器链,其中一系列过滤器应用于传入消息

您应该实现一个协议解码器(实现
MessageDecoder
),并将其注册到MINA过滤器链中。解码器应该将字节缓冲区解析为您选择的对象表示

然后,您可以注册一个处理完整消息的消息处理程序

如何获取个人信息

你没有。TCP中没有消息这样的东西。这是一个字节流协议。没有消息边界,也不能保证在另一端读一次等于写一次

(考虑到我无法在客户端中更改任何内容,并且单个消息的长度未知)


您必须根据应用程序协议的定义解析消息,以找到它们停止的位置。如果这是不可能的,比如说,因为协议不明确,客户端将不得不被废弃。然而,由于您无法更改客户端,它必须已经与现有系统一起工作,因此您之前的同事遇到了相同的问题,并以某种方式解决了它。

您能否发送服务器端代码的关键部分?对于这个问题,客户端代码没有帮助。但是在我的例子中,缓冲区包含多条消息的内容。e、 g:Msg1:Hai Tom,Msg2:Hai Peter。。当两者都在同一个套接字中发送时,在缓冲区中我得到BufferMsg:“Hai TomHai Peter”。如何在过滤器中执行此操作?从我所读到的关于过滤器的内容来看,这是不可能的。有什么帮助吗?也许你应该重新考虑你的协议设计。请记住,TCP套接字是一个管道:在接收端,您得到的是一个字节流,而不知道它们的预期碎片是什么。考虑在您的通道中使用一个协议来通知消息边界。常用的方法是在消息之间使用分隔符,例如字符“\0”,或者使用消息结构,在其中发送消息长度(字节、短或整数),然后发送消息正文中的字节数。不输出。flush()按你说的做吗?短答案有时是。您不能相信它会这样做,因为路由器(甚至本地tcp堆栈)可能会将多条消息合并为一条消息,或者将一条长消息分割为多条消息。底线是,TCP连接是一个双向管道;你不能使用任何你可以看到的字节序列之外的任何东西。(你可能想考虑UDP,其中消息是一条消息。但是你必须处理丢包、重新排序等)。 public static void main(String[] args) throws IOException, SQLException { System.out.println(Charset.defaultCharset().name()); IoAcceptor acceptor = new NioSocketAcceptor(); ProtocolCodecFilter(charset.newEncoder(),charset.newDecoder() )); acceptor.setHandler( new TimeServerHandler() ); acceptor.getSessionConfig().setReadBufferSize(64 ); acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ); acceptor.bind( new InetSocketAddress(PORT) ); } public void messageReceived(IoSession session, Object message) throws Exception { AbstractIoBuffer bf = (AbstractIoBuffer)message; Charset charset = Charset.forName("UTF-8"); CharsetDecoder decoder = charset.newDecoder(); String outString = bf.getString(decoder); }