在Socket网络程序中,一般通过InputStream和OutputStream来进行数据的通信的。
请问:
1. 命令间如何区分
假设我发送两个命令,接收方一般通过什么方法进行区分?我是指定数据包的格式,如:
命令ID + 命令文本 + 数据长度 + 数据
UTF文本  UTF文本    Long型     byte[]型
是否合理?或者有更加简单的方法?
2. 命令反馈
对于每个命令的反馈,是如何处理的?
同步命令:发送命令后一直等待,知道反馈的结果?
异步命令:将该命令Id存入,待得到某个结果后,再去命令存储区进行查找,这个命令反馈是干嘛的?
这样做是否合理?是否有点重新做轮子之嫌?有没有其他方法?

解决方案 »

  1.   

    自己这段时间也在搞类似的东西,所以来说说自己的做法。参考吧。
    首先我不觉得是重新发明轮子,这个问题应该是网络编程里永恒的问题之一。即使使用了封装好的东西,其实封装内部还是面临着同样的问题。而且,我想如果要封装的话,也许是比较麻烦的。
    先说区分的问题。我接触到的有几种方式。首先可以采用定长数据,比如你传一个int值,固定用4byte,这种情况下不用区分。不过这种方式的副作用是也许以后在某种场合下标识1个int用了8byte,那么就有些麻烦,数据发送方需要小心。加分隔符也是个办法,比如你传一个String类型的数据,末尾都用两个值为0的byte分隔,当然,这办法一般只用来对付String类型。先传数据长度,然后紧跟着传数据也是个主意,向你写的那样。如果数据长度是变化的,还是用这方法比较简单明了。一个典型的数据包:
    包总长(4byte)+命令字(2byte)+数据1(4byte)+数据2(?byte,String类型,以00结尾的byte[])
    反馈的问题。一种基本的交互模式是“请求-应答”模式,就像最原始的http Server和浏览器的工作模式那样。这种模式下,一次通讯是由两部分构成,任何两次通讯之间都是不耦合的。但要求设计通讯协议的时候必须保证协议之间是解耦的。工作时,收到一个处理一个,处理不同的命令之间没有先后顺序,可以并行处理。一个命令的处理被延迟后不会直接干扰其它命令的正确处理,但有可能通过改变某种状态而影响到其它协议,这个要自己检查。
    另一种方式就如你所说的“异步命令”,但不是说“查找命令反馈是干嘛的”,因为通过命令字一定可以知道它是用来干嘛的,其核心是一个命令或一条协议与其它的命令或者协议耦合,就是这个命令怎样处理需要依赖于一个别的命令的内容或处理结果。这时候重要的是正确建立处理顺序和对应关系。比如设计一组这样的协议,一条协议发送人名,年龄,一条协议发送照片,接收方处理时,必须当人名,年龄和照片都收到了,才写入一个数据库。那么,当通过一个协议收到了人名和年龄之后,必须等待与它相关联的照片收到后才能继续处理。这时候,没有对应关系是不可能的。我得做法是在发送方生成一个全局唯一id,传数据的同时附带id。反正比较麻烦。这种协议耦合的情况个人认为最好越少越好。