1、这个是pos程序,我们要和银商的某个系统对接,他们是c的p端,我是java的p端。我们要把pos端发送的报文转发到他们c的p端。
2、对方的报文要求使用ascii码形式传送。
3、通讯是单工长连接,就是需要两个socket,分别进行收和发。现在发送就有问题,所以还没管接收的socket。
4、现在的问题:和对方建立连接后,我们发出报文,但对方收到的是空的,或者没收到。
5、程序没有报错,所以我们搞了几天都没头绪,不知道问题可能在哪里。现在项目挺紧迫的,我们两个人卡在这几天了,感谢大侠们的帮助!
代码(我只贴出主要的代码):
发送程序PrepaidPosClient.java public boolean connect() {
boolean success = false;
try {
if (socket == null) {
socket = new Socket(host, port);
socket.setKeepAlive(true);// 开启保持活动状态的套接字
socket.setSoTimeout(60 * 1000);// 设置超时时间
success = true;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return success;
} public boolean sendMessage(Socket socket, byte[] msg) {
// DataOutputStream out =null;
DataInputStream dis = null;
DataOutputStream dos = null;
try {
if (socket.isConnected()) {
dis = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
dos = new DataOutputStream(socket.getOutputStream());
dos.write(msg);
logger.info("请求报文:" + ISOUtil.hexString(msg));
dos.flush();// 发送信息至第三方
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
} public static void main(String args[]) {
PrepaidPosClient prepaidReqest = new PrepaidPosClient("127.0.0.1",
Integer.parseInt("7778"));
boolean isSendMsg = false;
String str = "0110702004C020C11811188010000010650363513100000000000010000001980210000637801000001065036351D11022574108204049803130";
if (prepaidReqest.connect()) {
isSendMsg = prepaidReqest.sendMessage(prepaidReqest.getSocket(),
str.getBytes());
} }
socket单工 长连接socket单工长连接pos

解决方案 »

  1.   

    接收端那边数据接收是个什么结构体,你最好搞清楚.由于c端下面编译器默认会帮你做一些字节对齐的工作,所以有时候实际的字节数可能会更大.
    同时你也最好注意一下端序的问题,对方是按小端序接收还是大端序接收.和C通信,一般很难这么简单的用流来直接输出....
    最后喷一下你的代码...异常直接"e.printStackTrace();"....你就不能至少在日志里打印一下?在生产环境下你准备怎么找到连接失败的原因按照你的这个"connect()"方法的做法.
      

  2.   

     你自己用java模拟一个接收端正常否?
      

  3.   

    这个要看对方的协议,你是 dos = new DataOutputStream(socket.getOutputStream());
    就过去了,他那边是如何收的
      

  4.   

    回复2楼:小端序、大端序,是什么?
    我们这个是处理pos交易的,都是按照iso8583来的,最终发送的数据是十六进制的。
    我们自己用java端接受是正常的。昨天换了mina,然后对方就接受到了。真是郁闷呐,现在还不知道问题在哪里。
      

  5.   

    http://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F这是维基百科对于端序的说明.
      

  6.   

    不要使用 DataOutputStream 
      

  7.   

    试下调用setTcpNoDelay(true)方法,关闭Socket的缓冲,确保数据及时发送:
    if(!socket.getTcpNoDelay())socket.setTcpNoDelay(true);
      

  8.   

    麻烦问下您,我现在要连接考勤机,知道考勤机的IP和端口,测试连接   我的代码如下
    /**
     * 测试考勤机连接
     * @param atConfig
     * @return
     */
    public boolean testAttendanceConnection(AttendanceConfig atConfig){
    boolean result = false;
    HttpURLConnection con;
    try{
    HttpURLConnection.setFollowRedirects(false);
    String url = "http://"+atConfig.getIpaddress()+":"+atConfig.getPort();
    con = (HttpURLConnection) new URL(url).openConnection();
    con.setRequestMethod("HEAD");
    System.out.println("state code:"+con.getResponseCode());
    if(con.getResponseCode() == HttpURLConnection.HTTP_OK){
    result = true;
    }
    //URLConnection connection = (HttpURLConnection)url.openConnection();
    }catch(Exception e){
    e.printStackTrace();
    result = false;
    }
    return result;
    }但是测试的时候会有问题:
    java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:168)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:652)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1064)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:373)
    at cn.com.gf.convert.logic.AttendanceConnection.testAttendanceConnection(AttendanceConnection.java:42)
    at cn.com.gf.convert.logic.ConvertMonitor.testAttendanceContact(ConvertMonitor.java:215)
    at cn.com.gf.convert.ui.frame.MainFrame.actionPerformed(MainFrame.java:349)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6216)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5981)
    at java.awt.Container.processEvent(Container.java:2041)
    at java.awt.Component.dispatchEventImpl(Component.java:4583)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4413)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150)
    at java.awt.Container.dispatchEventImpl(Container.java:2085)
    at java.awt.Window.dispatchEventImpl(Window.java:2475)
    at java.awt.Component.dispatchEvent(Component.java:4413)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)麻烦您帮我解决下  
      

  9.   

    POS 传送报文件是定长 的文件,socket 需要accecpt() 打开后,才可以,发送报文。
      

  10.   

    1、你用于发送的数据已经转为byte[]了,就不要再通过DataOutputStream脱裤子放屁了;
    2、如果你非要用DataOutputStream包装一层,那么你的send...方法就应该传入的是这个输出流,而不应该是socket,否则你的每一次发送都会将流重新包装一次,这里包含了很多关于缓冲区控制,何时具体flush的问题(并发时才容易发现);
    3、通常长连接通讯需要解决报文片段的分界问题,银行的交易通讯很多是通过前导若干位的长度定义了界定多个报文体的,我初步判断你的这次报文发送没有前导的长度定义,这种通讯格式那边能正确接受就怪了,所以你可以从你的通讯数据包上找找问题;
    4、对方说没有收到,你认为你写的不对,这是基于你假设对方的系统很靠谱,所以你推导出你的代码有问题,建议你自己写一个简单的Socket监听程序,收到任何数据直接打印控制台,然后修改你的配置将IP指向到你的监听程序,看看是否真的什么也收不到,因为收不到可以由两种可能,一种确实是0数据包,还有一种就和第3点的问题呼应,也就是对方收到了6位长度头定义后(假设约定的是前导6位长度定义),但是你这个被误认为长度定义的数值太大,那边收不到这么多后续数据流,因此认为是没有收到数据!
      

  11.   

    直接向InputStream里面写入byte数组中的数据。
      

  12.   

    首先:确认对方的结构体是什么样的,这个很重要,最好是让对方提供几个结构体完整输出流所导出的 byte[] 给你们参考。其次:严禁使用DataOutputStream,它为了能够传递各种对象,会自行增加前导数据。最后:输出时应该直接输出你组装好的 byte[],不要逐个逐个的按类型输出,也不要输出String。