TCP套接字接收和处理多个消息 [英] TCP Socket receiving and processing multiple messages

查看:106
本文介绍了TCP套接字接收和处理多个消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在获取来自TCP套接字的所有数据时遇到了一些麻烦。

I'm having some troubles in getting all the data coming from a TCP socket.

在我的服务器中,我从这样的套接字读取数据:

In my server, I'm reading data from a socket like that:

        int len;
        byte[] buffer = new byte[2000];
        try {
            this.in = new DataInputStream(this.socket.getInputStream());
            this.out = new DataOutputStream(this.socket.getOutputStream());
            running = true;

            while (running) {
                len = in.read(buffer);
                if (len < 0) {
                    running = false;
                } else {
                    parsePacket(buffer, len);
                }
            }

        } catch (IOException ex) {
            System.out.println("Catch IOException: " + ex);
            ex.printStackTrace();
        } finally {
            try {
                System.out.println("Closing");
                in.close();
                out.close();
                socket.close();
            } catch (IOException ex) {
                System.out.println("Finally IOException: " + ex);
            }
        }

数据包格式如下:

[标题] [数据] [终止符]


  • 标题->标识消息开头的字符序列(没有有关数据包长度的信息);

  • 数据->分为多个段,例如: [大小段1] [数据段1] [尺寸段。 2] [数据段2] [尺寸段。 3] [数据段。 3] .... [尺寸段。 N] [数据段。 N]

  • 终结者-> [0x00]

数据为接收速度非常快(有时为200毫秒或更短),因此有时 read(buffer)用以下消息填充 buffer

The data are received very fast (sometimes 200ms or less), so sometimes the read(buffer) fills the buffer with messages like:


  • [HEADER1] [DATA1] [TERM1]或

  • [HEADER1] [DATA1] [TERM1] [HEADER2] [DATA2] [TERM2] .......... [HEADER N] [DATA N] [TERM N]或

  • [HEADER1] [DATA1] [TERM1] [HEADER2] [DATA2] [TERM2] ........... [HEADER N] [DAT(最后一条消息不完整)

parsePacket()方法能够解析具有上述格式的消息,如果接下来还有更多消息,它们也将被解析(递归)。但是如果它不完整,它不会解析最后一条消息(我不想要那样,但是直到现在我还没有找到合适的解决方案)。

The parsePacket() method is able to parse a message with the above format and if it has more messages next, they will be parsed also (recursively). But it will not parse the last message if it is incomplete (I don't want that, but I didn't find a suitable solution until now).

数据消息内部的消息存储在MySQL数据库中(使用JDBC驱动程序)。消息的每次解析都可能涉及对数据库的多个查询。由于我仅使用一个线程来接收,解析和存储数据,因此代码的执行速度不如应有的快……应该尽快接收和存储数据。

The data coming inside the messages are stored in a MySQL database (using JDBC driver). Each parse of a message can involve multiple queries to the database. As I'm using just one thread to receive, parse and store the data, the execution of the code is not as fast as it should... The data should be received and stored as quickly as possible.

我想讨论一些要点:


  • 什么是获得所有这些的最佳方法?邮件中没有丢失一些邮件?

  • 如何改善数据接收和存储的方式? (应该尽快存储数据!)

推荐答案

由于TCP已经是流协议读取此数据的最简单方法是作为流。我将添加一个侦听器来处理事件。

As TCP is already a stream protocol the simplest way to read this data is as a stream. I would add a listener to process the events.

DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

try {
   while(true) {
       listener.startOfMessage();
       for(int segSize; (segSize = dis.readInt()) > 0;) {
          byte[] bytes = new byte[segSize];
          dis.readFully(bytes);
          listener.data(bytes);
       }
       int footer = dis.read();
       // check footer ??
       listener.endOfMessage();
   }
} catch(EOFException endOfStream) {
   // handle or ignore
} finally {
   // close everything.
}

当您自己进行缓冲时,还必须重新组合消息并保留不完整的消息,这在这里毫无用处。

When you do the buffering yourself, you have to also re-assemble the messages and retain incomplete messages which is allot of headache for no benefit here.


数据接收速度非常快(有时为200毫秒或更短)

The data are received very fast (sometimes 200ms or less)

每个您拥有的CPU 200 ms约为600,000,000个时钟周期。这是计算机的永恒。 :)

200 ms is about 600,000,000 clock cycles for every CPU you have. This is an eternity to a computer. :)

上面的代码应在200毫秒内处理20,000条消息。如果您还需要更多,则可以使用NIO,但我不认为您需要。

The code above should handle in the order of 20,000 messages in 200 ms. If you needed more than this you could use NIO instead, but I wouldn't assume you need to.


数据应存储为

The data should be stored as quickly as possible!

我怀疑MySQL很好,不是尽快,但我看不到您说不使用它的原因。

I suspect that MySQL is fine, it is not "as quickly as possible" but I don't see any reason in what you have said not to use it.

这篇关于TCP套接字接收和处理多个消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆