我现在要给服务器端发送数据,包括包头和包体,包头包体格式定义如下: 
通用数据包结构分为两部分,包头和包体: 
包头控制信息: 
编译时,结构体采用1byte对齐 
struct PktCtlMsg 

    unsigned long len; //4 byte //包的总长度,包头加正文长度之和 
    unsigned char factorycode;//1 byte //厂商编码(保留) 
    unsigned char progid;//1 byte //进程号 
    unsigned char morepkt;//1 byte //是否还有后续包(保留) 
    char cmd_id[10];//10 byte //命令字,最大长度为9,不足位补空格 
        long start_num;//4 byte //起始记录号(保留) 
    long end_num;//4 byte //终止记录号(保留) 
    long request_id;//4 byte //请求号 
    long answer_id;//4 byte //应答号(保留) 
    long sequence;//4 byte //包序号 
    char link_user[9];//9 byte //连接的用户名(保留) 
    char link_pwd[9];//9 byte //连接的密码(保留) 
    short errorcode;//2 byte //返回码(保留) 
}; 2) 协议包结构:编译时,结构体采用1byte对齐 
struct PktMsg 

    struct PktCtlMsg  CtlMsg; //包头控制信息 
    char datatrans[1]; //传送内容,从datatrans开始为协议正文,格式为XML文本}; 
现在我要传送的包体xml格式的数据为: 
<?xml version="1.0" encoding="GB2312"?> <NewNSPasswordCompare AttrType="NewNSPasswordCompare" Verb="Retrieve"> <AreaCode AttrType="String">0931 </AreaCode> <CompareType AttrType="String">1 </CompareType> <ProuductType AttrType="String">1 </ProuductType> <Number AttrType="String">8788330 </Number> <CertificateType AttrType="String"> </CertificateType> <PassType AttrType="String">1 </PassType> <PassWord AttrType="String">000000 </PassWord> <PassCode AttrType="String">1 </PassCode> <Channel AttrType="String">web10000 </Channel> <StaffNo AttrType="String">web10000 </StaffNo> </NewNSPasswordCompare> 
我现在要把这个数据传过去,我该怎么写啊?第一次做这个,不懂,望赐教

解决方案 »

  1.   

    直接用socket来写不就可以了具体看看socket的客户端例子,或者上网找一下
      

  2.   

    我也正在找socket的资料,关注中.../
      

  3.   

    LZ首先要理解网络通讯到底是怎么回事,这里不考虑通讯协议的问题
    因为socket应该就是基于TCP/IP了
    他其实就是发送的二进制数据流
    所谓包结构就是指一段完整数据流里的信息是怎样的
    从多少字节到多少字节里存储的什么信息
    不知道这样说能明白吗?
      

  4.   

    直接写...
    OutputStream.write(byte[])另外..
    struct PktMsg 

        struct PktCtlMsg  CtlMsg; //包头控制信息 
        char datatrans[1]; //传送内容,从datatrans开始为协议正文,格式为XML文本}; 正文长度 1??
      

  5.   

    银行后台交易网关,他们叫前置机的服务,都是提供这种格式的通讯方式,不过有个很明显的区别,头部的长度定义,不包含头部本身的长度!
    我们在应用层通常不习惯使用这种晦涩的数据结构,所以在应用和后台之间架设了专门的统一数据平台,向应用统一提供XML结构的数据,后端可以是任意的第三方服务,当然也包括楼主说的这种格式的简单文本协议,而且是用的最多的!
    单纯写个程序处理一个这样的交易,把定长格式转化为XML,没有太多技术难点,就是烦,而且极容易出错!
    我的解决方案是自己写一个流程调度引擎,完全配置化地调度各个部件,实现这些转化过程,全过程都依赖XML的XPath,前端使用Web容器,提供HTTP协议的XML交换,也可以在负载均衡点前端加上一个自己写的代理(这个代理没有经过考验,压力上没什么信心)提供简单文本协议来交换XML数据!楼主说的这个问题,在整个解决方案中只是一个处理器,这个转化的过程估计楼主还漏了几点没说到:
     1、每个字段的对齐方式;
     2、每个字段在原始数据不足时(即占不满所有位时),用什么字符补齐;
    转换过程一般会有两步,从XML中抽取相应字段填充到byte[]
       中间有一个过程是直接拿这个byte[]与第三方服务器交换
    交换到的byte[],再依照接口格式,从相应位置抽取出组成XML各个字段需要的数据!
    通常转化过程还包括一些多行数据的问题
    我不知道楼主做的东西是不是我说的这样,你提的问题应该是第一个转换过程,从XML中抽取相应字段填充到byte[]
    不过我看楼主似乎从前是用的Unix C来实现的吧,其实主要的难点不在转换的过程,而是如何将整个过程配置化!一直以为自己做的这个东东很冷门,今天终于看到同道了,出来吼一吼!
    以下是我的解决方案中,某个交易的这三个过程的配置,楼主可以参考一下:
                    <processor imp="processor.XMLToBytes" attach="CRequest">
    <include src="/config/djk/public.xml/*/requesthead/*" />
    <field length="6">500020</field>
    <field name="CardNo" length="21" align="right" fix=" " ></field>
    </processor>
    <processor imp="processor.CSocket" request="CRequest" response="CResponse" reqHead="ReqHead" respHead="RespHead">
    <include src="/config/djk/public.xml/*/port30012/server" />
    </processor>
    <processor imp="processor.BytesToXML" attach="CResponse">
    <field name="SetAmt" length="17" ></field>
    <field name="DefAmtV" length="17" ></field>
     <rows name="Detail" size="Rec1">
    <field name="BalCom" length="3" ></field>
    <field name="OldCycIst" length="17" ></field>       
    </rows>
    </processor>
      

  6.   

    两个结构体,可以对应两个Java类。
    对于PktMsg结构体对应的Java类,需要编写一个byte [] getBytes()方法,返回一个信息包的比特数组,
        或者void write(Writer writer)方法,将该对象对应的byte数组写入IO流,
        用于网络传输。PktMsg结构体当中char datatrans[1]; 可能有些不对,按我理解,应该是个char数组,也就是:char[] * datatrans ;至于PktMsg结构体对应的Java类当中, char datatrans[1];对应的成员变量,到底用什么来表示,
        要看楼主的具体程序环境,如果使用什么Dom4j之类的,那就用Document的引用来做成员变量;当然,不反对其他类型的成员变量,
        比如byte []类型,String类型,自定义的类型。具体怎样编码,协议里面应该都有明确的说明,查一查,就能搞定了。
      

  7.   

    1.第一个结构体可以写成一个javabean对象!所有的字段都让它自动生成getter和setter方法,然后重写toString方法!
    public String toString()
    {
        //1.将所有字段的值组成一个字符串
        //2.然后return这个字符串
    }
    以后只要new了这个bean对象,在set完所有的字段后直接调用toString方法就能得到所有字段组成的包头信息(可设置一个字符串(如strHead)存取)了!
    2.将xml文本用输入流来读取,然后将其存入一个字符串中(比如:strInfo)3.将strHead与strInfo合并,存入到一个strMsg中。然后strMsg.getByte()得到的字节数组用socket方式发送出去即可!import java.net.*; 
    public class UdpSend 

        public static void main(String [] args) throws Exception 
        { 
              DatagramSocket ds=new DatagramSocket(); 
              strMsg=strHead+strInfo;
              DatagramPacket dp=new DatagramPacket(strMsg.getBytes(),strMsg.lengt(),InetAddress.getByName(服务器IP,端口号); 
              ds.send(dp); 
              ds.close(); 
        } 

    //服务器IP,端口号 自己指定!!
      

  8.   

    可以将PktCtlMsg写成一个类,然后实现这个类的包装和解析方法
    注意参数之间的前后顺序和所占字节的大小
    可以用ByteBuffer来存放所要传送的数据信息