基于Java语言实现Socket通信

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012449363/article/details/78522554

基于Java语言实现Socket通信

由于近日项目需求,需要在服务器中增加Socket通信的功能,接收硬件设备发送的心跳包和相关数据,因此又重新对Java的网络编程进行了复习,根据项目的实际情况做了简化的编程,实现了简单的通信过程。

1. Socket通信原理

源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务。
以下是通过Socket套接字实现客户端与服务器端通信的示意图:

在实际应用中,客户端会通过访问服务器的IP和PORT连接到服务器端,这个过程在服务器和客户端之间创建一个Socket,然后通过I/O数据流实现数据传输,也就是Socket的通信过程。

2. 服务器端

服务器端模拟接收硬件设备传输的心跳包(一个长度为10的字节数组),服务器端会获取到心跳包以及硬件设备的地址和端口号。

public class Server extends Thread{
    //服务器端口号
    private int port;
    private ServerSocket server = null;

    public Server(){
        //创建一个服务器,同时可以接收10个设备发送的数据
        server = new ServerSocket(port,10);
        System.out.println("Socket服务器启动,开始接受数据");
    }

    @Override
    public void run(){
        while (true) {
            Socket socket = null;
            InputStream inputStream = null;
            OutputStream outputStream = null;
            byte[] inputData = new byte[1024];
            try {
                //接收Socket数据
                socket = server.accept();
                //获取远程采集机的IP和端口号
                String remoteAddress = socket.getInetAddress().toString();
                int remotePort = socket.getPort();
                inputStream = socket.getInputStream();
                //获取传入的数据长度
                int length = inputStream.read(inputData);
                //创建输出流向客户端返回信息
                outputStream = socket.getOutputStream();
                if (length == 10) {
                    //如果长度等于10,说明传入的是心跳包
                    System.out.println("接收到心跳包,客户端信息["+remoteAddress+":"+remotePort+"]");
                    outputStream.write("success".getBytes());
                } else {
                    System.out.println("接收的信息有误.");
                    outputStream.write("failed".getBytes());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                    if (socket != null) {
                        socket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    //省略Getter和Setter方法
}

3. 客户端

客户端负责每隔一段时间向服务器发送一个心跳包。

public final class Client {
    private String address = "";
    private int port = 0;


    private Socket socket = null;

    private Client() {
    }

    private Client(String address, int port) throws IOException {
        this.address = address;
        this.port = port;
        this.socket = new Socket(address, port);
    }

    public static byte[] sendCommand(String address, int port, byte[] data) {
        Client client = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        byte[] recevie = new byte[40];
        try {
            client = new Client(address, port);
            outputStream = client.getSocket().getOutputStream();
            outputStream.write(data);
            System.out.print("Send Data Success");
            inputStream = client.getSocket().getInputStream();
            inputStream.read(recevie);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                outputStream.close();
                client.getSocket().close();
            } catch (IOException ioe) {
                System.out.print("IOE when closing resource");
            }
        }
        return recevie;
    }

    /**
     * 测试函数
     */
    public static void test() {
        for (int i = 0; i < 10; i++) {
            //服务器地址和IP
            String address = "127.0.0.1";
            int port = 9000;
            //心跳包
            byte[] data = "#$*beat001".getBytes();
            String receive = new String(Client.sendCommand(address, port, data));
            System.err.println("第" + i + "次发送心跳包" + receive);
            try {
                //每隔2分钟发送一个心跳包
                Thread.sleep(2 * 60 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //省略Getter和Setter方法
}

4. 总结

目前的这种方式比较像目前共享单车的通信模式,通过心跳包来获取Client的IP和PORT,然后Server就可以通过心跳包上传的IP和PORT主动的向Client通信了。其他的物联网项目也可以使用这样的方式,这样就可以实现主动的与物联网设备的通信了,只需要规定好协议和传送数据了。 

展开阅读全文

没有更多推荐了,返回首页