如何定义包头、包体,如何发送和接收??对这块不是很清楚,请知情人给讲解下。

解决方案 »

  1.   

    自定义数据包需根据双方约定的协议进行,在协议里会定义包头,包体的长度,类型,数据校验等发送和接收用Socket编程
      

  2.   

    兄弟这个是http 协议的 我原来写的 给你部分代码参考package com.sjy.ying;import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;import javax.microedition.io.Connector;
    import javax.microedition.io.HttpConnection;public class MassageSend {

    String receiveuserid =null;

    String senduserid =null;

    String massage = null;


    public void getmassagelogin(String receiveuserid, String senduserid, String massage){
    this.receiveuserid = receiveuserid;
    this.senduserid = senduserid;
    this.massage = massage;
    } public void send() { HttpConnection hc = null;
    InputStream dis = null;
    OutputStream dos = null;
    // int temp = -1;
    String url = "http://localhost:8080/http/http"; try {
    hc = (HttpConnection) Connector.open(url, Connector.READ_WRITE);
    hc.setRequestMethod(HttpConnection.POST); hc.setRequestProperty("User-Agent",
    "Profile/MIDP-1.0Configuration/CLDC-1.0");
    hc.setRequestProperty("Content-Language", "en-US");
    hc.setRequestProperty("Accept", "application/octet-stream");
    hc.setRequestProperty("Connection", "close");
    hc.setRequestProperty("Content-Length", "222"); dos = hc.openOutputStream();
    } catch (IOException e) {
    System.out.println("网络连接失败,请查看网络连接");
    } try {
    dos.write('~');
    dos.write(receiveuserid.getBytes());
    dos.write(':');
    dos.write(senduserid.getBytes());
    dos.write('!');
    dos.write(massage.getBytes());

    System.out.println("wwwwwwwwwwwwwwww");// dis = hc.openInputStream();
    // StringBuffer sb = new StringBuffer();
    // while ((temp = dis.read()) != -1) {
    // // dos.write((char) temp);
    // // System.out.print((char)temp);
    // sb.append((char) temp);
    // }
    // temp = (char)dis.read();
    // System.out.println((char)temp); // System.out.print(temp);
    // } catch (IOException e) {
    // e.printStackTrace(); } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try { if (dis != null)
    dis.close();
    if (dos != null)
    dos.close();
    if (hc != null)
    hc.close();
    } catch (IOException e) {
    e.printStackTrace();
    } } }}
    qq群 希望共同进步30226591
      

  3.   

    有通过socket的吗,比如说用开源mina或者netty等。
      

  4.   

    实现Mina的 MessageDecoder 接口的 decodable 方法. 这个方法就是判断是不是该去解码了, 看我的代码吧: request 对象自己定义吧, 用定长的int描述不定长的数据即可.
    public class GroupUMessageDecoder implements MessageDecoder {
    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(MessageDecoder.class);
    private Charset charset;public GroupUMessageDecoder(Charset charset) {
    this.charset = charset;
    }/**
    * 检查给定的IoBuffer是否适合解码
    */
    public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
    // 报头长度==6
    if (in.remaining() < 6) {
    return MessageDecoderResult.NEED_DATA;
    }// tag正常
    short tag = in.getShort();
    if (tag == 1 || tag == 2) {
    logger.info("请求标识符:" + tag);
    } else {
    logger.error("未知的解码类型....");
    return MessageDecoderResult.NOT_OK;
    }// 真实数据长度
    int len = in.getInt();
    int remainLen = in.remaining();  
    logger.info("dataLength:{}, remainLength:{}", len, remainLen);
    if (remainLen < len) {
    return MessageDecoderResult.NEED_DATA;
    }
    return MessageDecoderResult.OK;
    }public MessageDecoderResult decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
    logger.info("解码:" + in.toString());CharsetDecoder decoder = charset.newDecoder();
    BaseMessage message = null;
    short tag = in.getShort(); // tag
    int len = in.getInt(); // length
    logger.info("解码数据长度:" + len);byte[] temp = new byte[len];
    in.get(temp); // 数据区// ===============解析数据做准备======================
    IoBuffer buf = IoBuffer.allocate(400).setAutoExpand(true);
    buf.put(temp);
    buf.flip(); // 为获取基本数据区长度做准备if (tag == 1) { // 简单类型Message
    SimpleMessageResponse resp = new SimpleMessageResponse();
    String txtMessage = "";
    if (len > 0) {
    txtMessage = buf.getString(len, decoder);
    }
    resp.setTxtMessage(txtMessage);
    message = resp;
    }  else if (tag == 2) {
    TxtImageMessageRequest resp = new TxtImageMessageRequest();
    //数据部分   
    // 1, 文字长度描述(32bit) + 文字内容
    int txtLen = buf.getInt();//文字的长度
    String txtMessage = "";
    if (len > 0) {
    txtMessage = buf.getString(txtLen, decoder);
    }
    resp.setTxtMessage(txtMessage);
    // 2, 图片数量
    int imageNum = buf.getInt();
    logger.info("received TxtMessage length:{}, message:{}, imageNum:" + imageNum, txtLen, txtMessage);
    // 2, 图片部分: 图片名称长度描述 图片长度. 图片在文字内容的位置(32bit) + 图片长度描述(32bit) + 图片数据
    while (imageNum-- > 0) {
    int imageNameLength = buf.getInt();//图片的名称的长度
    if (imageNameLength <= 0 )
    break;
    String imageName = buf.getString(imageNameLength, decoder);
    if (imageName == null || "".equals(imageName))
    break;
    logger.info("imageName:{}" , imageName);
    int imagePosition = buf.getInt();//图片的位置
    int imageLength = buf.getInt();//图片的长度
    if (imageLength <= 0)
    break;
    byte[] imageData = new byte[imageLength];
    buf.get(imageData);MessageImageInfo ii = new MessageImageInfo();
    ii.setImageName(imageName);
    ii.setImagePositionInTxt(imagePosition);
    ii.setImageData(imageData);
    resp.addImageInfo(ii);
    message = resp;
    break;
    }}
    out.write(message);
    // ================解码成功=========================
    return MessageDecoderResult.OK;
    }public void finishDecode(IoSession session, ProtocolDecoderOutput out)
    throws Exception {
    }
    }public class GroupUMessageEncoder implements MessageEncoder<BaseMessage> {private static final Logger log = org.slf4j.LoggerFactory.getLogger(GroupUMessageEncoder.class);
    private Charset charset;public GroupUMessageEncoder(Charset charset) {
    this.charset = charset;
    }public void encode(IoSession session, BaseMessage message,
    ProtocolEncoderOutput out) throws Exception {IoBuffer buf = IoBuffer.allocate(400).setAutoExpand(true);// ===========SimpleMessageRequest 编码数据区===============
    if (message instanceof SimpleMessageRequest) {
    SimpleMessageRequest req = (SimpleMessageRequest) message;
    buf.putShort((short) req.getTag());
    int dataLength = req.getLen(charset);
    buf.putInt(dataLength);
    log.info("SimpleMessageRequest dataLength:" + dataLength);
    buf.putString(req.getTxtMessage(), charset.newEncoder());
    log.info("SimpleMessageRequest 编码完毕:" + buf.toString());
    }  // ===========TxtImageMessageRequest 编码数据区===============
    if (message instanceof TxtImageMessageRequest) {
    TxtImageMessageRequest req = (TxtImageMessageRequest) message;
    buf.putShort((short) req.getTag());
    int dataLength = req.getLen(charset);
    buf.putInt(dataLength);
    System.out.println("dataLength:" + dataLength);//数据部分   
    // 1, 文字长度描述(32bit) + 文字内容
    int txtLength = req.getTxtMessage().getBytes(charset).length;
    buf.putInt(txtLength);
    buf.putString(req.getTxtMessage(), charset.newEncoder());
    // 2, 图片数量
    buf.putInt(req.getImageNum());
    // 3, 图片部分: 图片名称长度描述 图片长度. 图片在文字内容的位置(32bit) + 图片长度描述(32bit) + 图片数据
    if (req.getImageList() != null && req.getImageList().size() > 0) {
    for (MessageImageInfo mii : req.getImageList()) {
    if (mii.getImageData() == null || mii.getImageData().length == 0){
    log.warn("TxtImageMessageRequest Encode: image no data");
    continue;
    }
    int imageNameLength = mii.getImageName().getBytes(charset).length;
    buf.putInt(imageNameLength); //图片名称长度
    buf.putString(mii.getImageName(), charset.newEncoder()); //图片名称buf.putInt(mii.getImagePositionInTxt()); //图片位置
    buf.putInt(mii.getImageData().length); //图片数据长度
    buf.put(mii.getImageData()); //图片数据
    }
    }
    log.info("TxtImageMessageRequest编码完毕:" + buf.toString());
    }  buf.flip();
    out.write(buf);
    }
    }