RT

解决方案 »

  1.   

    好象是可以建立一种非阻塞的连接.如果是普通的input和output stream的话在连接的时候是阻塞方式的.channel可以工作在非阻塞的模式下,实现上似乎是用buffer实现的.不过我也没具体用过,就知道这么点了.
      

  2.   


     //打开一个针对面向流的连接套接字的可选择通道。 
        private SocketChannel openSocketChannel() throws IOException {        logger.debug(String.format("openning connection " +
                    "remote %s:%d, local %s:%d",
                    this.remoteHost, this.remotePort,
                    this.localAddress == null ? "*" : this.localAddress, this.localPort));        SocketChannel sch = SocketChannel.open();        try {
                Socket socket = sch.socket();            if (this.localAddress != null || this.localPort != 0) {                logger.trace("local address is not wild card address");                InetSocketAddress local = this.localAddress != null ? new InetSocketAddress(this.localAddress, this.localPort)
                            : new InetSocketAddress(this.localPort);                logger.trace("binding to local address " + local);                socket.bind(local);                logger.trace("bind local address ok");
                }            InetSocketAddress remote = new InetSocketAddress(
                        this.remoteHost, this.remotePort);            logger.trace("connecting remote host " + remote);            socket.connect(remote, this.connectTimeout);            logger.debug(String.format("connected to peer " +
                        "remote %s, local %s", socket.getInetAddress(), socket.getLocalAddress()));            logger.debug("read time out is set to " + this.readTimeout);            socket.setSoTimeout(this.readTimeout);        } catch (SocketTimeoutException tox) {            logger.error(String.format("connecting timed out " +
                        "remote %s:%d, local %s:%d",
                        this.remoteHost, this.remotePort,
                        this.localAddress, this.localPort), tox);            throw tox;        } finally {            if (!sch.isConnected()) {                logger.error(String.format("failed to open connection " +
                            "remote %s:%d, local %s:%d",
                            this.remoteHost, this.remotePort,
                            this.localAddress, this.localPort));
                    try {
                        logger.debug("close socket channel due to error");                    sch.close();                } catch (Exception x) {                    logger.debug("error when closing socket", x);
                    }
                }
            }
            return sch;
        }
      

  3.   

    当以上我打开了一个连接后,我会发送一个请求包过去,回来一个应答包
     余额查询
    服务类型100001,请求无包体,应答有包体。
    返回值:      成功                          00000
                  有异常或错误出现              00501
    应答包体:   
    名称 最大长度 格式
    执行结果 (2) 0表示正确查询 -1没有查询到该用户 -2其他错误
    用户话费余额 (10) 以“元”作单位,包含小数点
    注:应答包头中需要返回请求包头中的业务号码(A6)以及交易类型(A4)
    例如这个,但是返回的应答包中,会有执行结果和用户的话费余额,
    2包体定义 
    一个数据包总长度不可大于20k,对存在多条返回纪录的业务,一数据包可含多条记录。长度如超过20K,应以多包数据发送。字段长度定长,每字段之间用”TAB键0x09”分隔,每记录之间用“回车键0x0d,0x0a”分隔。
    注意:
    数据包若无包体,则长度为80,不包含0x1a;
    0x09只是字段之间的间隔符,最后一个字段结尾只有0x1a;
    0x0d,0x0a只是记录之间间隔符,最后一条记录结尾只有0x1a
    例一:
    字段1  +  0x09  +  字段2  +  0x09  +  字段3  +  0x1a  结束
    例二:
    记录1  +  0x0d 0x0a  +  记录2  +  0x1a  结束
    例三:
    记录1字段1  +   0x09  +   记录1字段2  +   0x0d 0x0a  +  记录2字段1   +   0x09  +   记录2字段2    +    0x1a   结束而在一个数据包的头5位总是代表整个数据包的长度,因为现在也没法测试,我想知道的是,这个长度会不会包括,0x09这些东西,
    按道理说应该是包含的...但是没法测试,所以想叫大家帮我看看,也好安心