小奋斗 - 轻松学习从此开始!
IT小奋斗群 QQ群:62017228

Java Web基础 Socket数据的接收

socket数据的接收与文件流有着很大的区别,今天我们就学习一下网络上socket数据的接收。

socket数据接收

一、正确的使用方式一

package com.datagram.huhx1;

import java.io.InputStream;
import java.net.Socket;

public class SocketTest1 {

    public static void main(String[] args) {
        Socket socket;
        try {
            socket = new Socket("192.168.XXX.XXXX", 8099);
            System.out.println(socket.isConnected());
            String data = "XXXXXXXXXXXXXXXXXXXXXXXX";
            socket.getOutputStream().write(data.getBytes());
            InputStream inputStream = socket.getInputStream();

            Thread.sleep(1000);
            int length = inputStream.available();
            byte[] buffer = new byte[length];
            inputStream.read(buffer);
            String string = new String(buffer, "gbk");
            System.out.println(string);
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如果不使用Thread.sleep(1000);的话,inputStream.available()会得到0。数据不会有效的读取。这种方式比较广泛,对不同的报文都有着比较好的效果,这主要取决于网络的环境。

二、一般来说,从socket中读取数据。数据会有着明显的特征。头部会有返回数据的信息。

package com.datagram.huhx1;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Arrays;

/**
 * @author huhx
 */
public class SocketTest2 {
    public static void main(String[] args) {
        Socket socket = null;
        try {
            socket = new Socket("192.168.40.195", 8027);
            System.out.println(socket.isConnected());
            
            // 00000265前8位是长度,00000207表示真实数据的长度,32个空白字符,810504表示交易码,RQ0固定, tp固定, 810504表示交易码,3固定。
            String data = "0000026500000207810504RQ0                                tp8105043<nbs_hk_seqno>20161024151954003554303</><terminal_device></><transdate>2016-10-24</><transtime>151954</><channelid>10</><bankcode>03</><flag>03</><idno>420107198702043713</><acctno>2291</><bankacctno>2405</>";
            String data2 = "<nbs_hk_seqno>20161024151954003554303</><terminal_device></><transdate>2016-10-24</><transtime>151954</><channelid>10</><bankcode>03</><flag>03</><idno>420107198702043713</><acctno>2291</><bankacctno>2405</>";
            String data3 = "                                ";
            System.out.println(data3.length()); // 32
            System.out.println(data2.length()); // 207
            System.out.println(data.length()); // 273 = 265 + 8

            // 发送socket数据
            socket.getOutputStream().write(data.getBytes());
            InputStream inputStream = socket.getInputStream();
            System.out.println(inputStream.available()); // 0 网络上使用这个,不靠谱

            // 读取头部的信息 -- 前8位是长度信息
            byte[] lenBytes = new byte[8];
            inputStream.read(lenBytes, 0, 8);
            int readLength = Integer.parseInt(new String(lenBytes));

            // buffers是总的返回报文
            byte[] buffers = Arrays.copyOf(lenBytes, readLength + 8);
            inputStream.read(buffers, 8, readLength);
            String realStr = new String(buffers, "gbk");
            System.out.println(realStr);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这个比上述要明理一些,是专门针对公积金报文来写的。换做是其它格式的报文,这个方法会失效。在这其中,有一个比较重要的学习:Integer.parseInt方法。如下:

String string = "000000236";
System.out.println(Integer.parseInt(string)); // 236

三、记录一下失败的过程

  • 直接使用inputStream.read():数据可以读取出来,但是在while循环里没有结果,数据不会继续打印。while外面的代码不会执行,直接卡在while循环中。
  • 使用inputStrea.avaliable():这个在第一种方法用到过,如果直接使用。得到会是0,所以上述用了sleep。
  • 使用BufferedReader的readLine()方法,直接没有任何输出,和第一种类似的现象。

我来评几句
登录后评论

已发表评论数(0)