Java中的应用程序层协议头字段

时间:2015-10-12 06:37:19

标签: java

我希望这个问题适合这里。我设计了一个应用层协议,类似于HTTP。如何在Java中定义和设置标题字段?总的来说,我只想写一个简单的客户端服务器程序,它传输“Hello World”字符串,但使用我自己的协议。

假设标题字段类似于以下内容。那么“Hello World!”数据出现在此标题之后。

enter image description here

2 个答案:

答案 0 :(得分:1)

当您写入套接字时,您正在编写字节流。正如您在问题中包含的表中一样,通常使用标准字节序列来启动该流,这些字节提供了理解剩余流所需的信息。

例如,您只想发送一个字符串,您需要添加的最小字符串长度如下:

|message length|data|

可以这样写:

String data = "Hello, world!";

ByteBuffer buffer = ByteBuffer.allocate(data.length + Integer.BYTES);
buffer.putInt(data.length);    
buffer.put(data.getBytes("UTF-8"));
buffer.flip();

channel.write(buffer);

添加额外的标题信息也不例外,您只需要在流中为其定义格式。

例如,您可以使用这样的格式

|message length|header count|header size|header type|header data|data|

可以这样写:

Map<Integer, String> headers = ...
String data = "Hello, world - look at my headers!";

int headerBuffersLength = 0;
List<ByteBuffer> headerBuffers = new ArrayList<>();

for(Integer headerType : headers.keySet())
{
  String headerData = headers.get(headerType);

  ByteBuffer headerBuffer = ByteBuffer.allocation(headerData.size + Integer.BYTES + Integer.BYTES);
  headerBuffer.putInt(headerData.length);
  headerBuffer.putInt(headerType);
  headerBuffer.put(headerData.getBytes("UTF-8"));
  headerBuffer.flip();

  headerBuffers.add(headerBuffer);

  headerBuffersLength += headerBuffer.limit();
}

ByteBuffer buffer = ByteBuffer.allocate(data.length + headerBuffersLength + Integer.BYTES + Integer.BYTES);
buffer.putInt(data.length + headerBuffersLength);    
buffer.putInt(headerBuffers.size());

for (ByteBuffer headerBuffer : headerBuffers)
{
  buffer.put(headerBuffer);
}

buffer.put(data.getBytes("UTF-8"));
buffer.flip();

channel.write(buffer);

这是基础知识,编写代码非常简单,但如果你做了更复杂的事情,你可能想看看Google Protocol Buffers

答案 1 :(得分:0)

有很多方法。这种规范附带xsd是很常见的。如果是这种情况,您可以使用JAXB2来解析它并创建一组Java类。

如果不是这种情况,您可能会使用grepsed等方式进行文本处理并提取属性和类型以自动化Java类构造。上。

如果最后你必须自己构建Java类,我会做类似下面的事情:

package my.package.ams;

public class ASMHeader {
    private Integer version = null;
    private Integer msgType = null;
    private Integer priority = null;
    ...

    public String getVersionString (){
        return String.format("%02d", (version != null)?version:0);
    }

    public Integer getVersion(){
        return version;
    }

    public void setVersion(Integer version){
        if(version >= 0 and version < 100){
            this.version = version;
        }
    }

    public Integer getMsgType(){
        return msgType;
    }

    public void setMsgType(Integer MsgType){
        if(msgType >= 0 and msgType < 5){
            this.msgType = msgType;
        }
    }

    //And so on

    ....
} 

最后处理规则没有显示在你的脚本中,但你必须理解和实现。

考虑在versionmsgType和其他变量不符合文档中表达的规则的情况下抛出异常的可能性。

希望它有所帮助!