我希望这个问题适合这里。我设计了一个应用层协议,类似于HTTP。如何在Java中定义和设置标题字段?总的来说,我只想写一个简单的客户端服务器程序,它传输“Hello World”字符串,但使用我自己的协议。
假设标题字段类似于以下内容。那么“Hello World!”数据出现在此标题之后。
答案 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类。
如果不是这种情况,您可能会使用grep
,sed
等方式进行文本处理并提取属性和类型以自动化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
....
}
最后处理规则没有显示在你的脚本中,但你必须理解和实现。
考虑在version
,msgType
和其他变量不符合文档中表达的规则的情况下抛出异常的可能性。
希望它有所帮助!