zoukankan      html  css  js  c++  java
  • Java中Socket通信-服务端和客户端双向传输字符串实现

    场景

    什么是socket

    在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。

    socket 的典型应用就是 Web 服务器和浏览器:浏览器获取用户输入的 URL,向服务器发起请求,服务器分析接收到的 URL,将对应的网页内容返回给浏览器,浏览器再经过解析和渲染,就将文字、图片、视频等元素呈现给用户。

    那么在Java中怎样使用import java.net.Socket;来构建服务端和客户端并进行通信传输字符串?

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    ServerSocket类能创建Socket(套接字)的服务端,Socket类能创建Socket的客户端。

    在代码层面使用的方式就是使用Socket类去连接ServerSocket类,也就是客户端要主动连接服务端。

    ServerSocket类中的public Socket accept()方法的作用是侦听并接受此套接字的连接。此方法在连接传人之前一直阻塞。public Socket accept()方法的返回值是Socket类型。

    那么什么时候不阻塞呢?有客户端连接到服务端时就不再出现阻塞了,服务端的程序会继续运行。

    除了ServerSocket类中的accept()方法具有阻塞特性外,InputStream类中的read()方法也同样具有阻塞特性。

    通过使用Socket类的getlnputStream()方法可以获得输人流,从输人流中获取从对方发送过来的数据

    客户端向服务端发送字符串数据

    首先新建一个Java项目SocketServer作为服务端

    然后编写其main方法,在main方法中调用接收并读取字符串的方法

    package com.badao;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Main {
    
        public static void main(String[] args) {
    
            //接受并读取客户端发送的字符串
            getStringFromClient();
    
        }
    
        //接受并读取客户端发送的字符串
        public static  void getStringFromClient()
        {
            try {
                char[] charArray = new char[10];
                //创建Socket服务端,开放端口8088
                ServerSocket serverSocket = new ServerSocket(8088);
                System.out.println("accept begin = " + System.currentTimeMillis());
                //调用accept方法,此时会堵塞
                Socket socket = serverSocket.accept();
                System.out.println("accept end =" + System.currentTimeMillis());
                //获取客户端发送的数据的输入流
                InputStream inputStream = socket.getInputStream();
                //读取输入流
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                System.out.println("read begin =" + System.currentTimeMillis());
                int readLength = inputStreamReader.read(charArray);
                while (readLength != -1) {
                    String newString = new String(charArray, 0, readLength);
                    System.out.println(newString);
                    readLength = inputStreamReader.read(charArray);
                }
                System.out.println("read end =" + System.currentTimeMillis());
                inputStreamReader.close();
                inputStream.close();
                socket.close();
                serverSocket.close();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    然后在新建一个Java项目SocketClient作为客户端,同样新建一个main方法,并在main方法中调用发送字符串数据

    到服务端的方法

    package com.badao;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class Main {
    
        public static void main(String[] args) throws IOException, InterruptedException {
    
        //客户端向服务端发送字符串
        sendStringToServer();
    
        }
    
        //客户端向服务端发送字符串
        public static void sendStringToServer() throws IOException, InterruptedException {
            System.out.println("socket begin ="+System.currentTimeMillis());
            //新建客户端并请求服务端的ip为localhost 端口为8088
            Socket socket = new Socket("localhost",8088);
            System.out.println("socket end ="+System.currentTimeMillis());
            //休眠3秒
            Thread.sleep(3000);
            //获取客户端的输出流 即向服务端发送的数据
            OutputStream outputStream = socket.getOutputStream();
            //向输出流中写入要发送的字符串数据
            outputStream.write("公众号:霸道的程序猿".getBytes());
            outputStream.close();
            socket.close();
        }
    }

    然后运行服务端的main方法

    此时服务端会一直堵塞在accept方法这里,一直等待客户端发送数据。

    然后运行客户端的main方法,实现客户端向服务端发动字符串数据,此时服务端接收到客户端的字符串数据

    服务端向客户端发送数据

    在服务端的项目中新建向客户端发送字符串数据的方法

        //服务端向客户端发送字符串数据
        public static void sendStringToClient() throws IOException {
            //新建Socket 服务端 并开放8088 端口
            ServerSocket serverSocket = new ServerSocket(8088);
            System.out.println("server堵塞开始 =" + System.currentTimeMillis());
            //获取socket
            Socket socket = serverSocket.accept();
            System.out.println("server堵塞结束 ="+System.currentTimeMillis());
            //socket发送数据
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write("来自服务端-公众号:霸道的程序猿".getBytes());
            outputStream.close();
            socket.close();
            serverSocket.close();
        }

    然后在main方法中取消运行上面的方法,改为运行此方法

        public static void main(String[] args) throws IOException {
    
            //接受并读取客户端发送的字符串
            //getStringFromClient();
            //服务端向客户端发送字符串数据
            sendStringToClient();
    
        }

    然后再客户端项目中新建接受服务端数据的方法

       //客户端接收来自服务端的数据
        public  static void getStringFromServer() throws IOException {
            System.out.println("client连接准备就绪 =" + System.currentTimeMillis());
            Socket socket = new Socket("localhost",8088);
            System.out.println("client连接成功结束 ="+System.currentTimeMillis());
            char[] charArray = new char[10];
            //获取客户端发送的数据的输入流
            InputStream inputStream = socket.getInputStream();
            //读取输入流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            System.out.println("read begin =" + System.currentTimeMillis());
            int readLength = inputStreamReader.read(charArray);
            while (readLength != -1) {
                String newString = new String(charArray, 0, readLength);
                System.out.println(newString);
                readLength = inputStreamReader.read(charArray);
            }
            System.out.println("read end =" + System.currentTimeMillis());
            inputStreamReader.close();
            inputStream.close();
            socket.close();
        }

    然后在main方法中取消运行上面的方法,改为运行此方法。

    首先运行服务端的main方法

    此时服务端会堵塞,直接运行客户端的main方法启动客户端之后

    博客园: https://www.cnblogs.com/badaoliumangqizhi/ 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
  • 相关阅读:
    C# Excel操作类 ExcelHelper
    转战JS(1) 初探与变量类型、运算符、常用函数与转换
    jQuery插件实例五:手风琴效果[动画效果可配置版]
    jQuery插件实例四:手风琴效果[无动画版]
    安装nvm之后node不可用,“node”不是内部或外部命令,也不是可运行的程序或批处理文件(ng)
    git常用命令简集
    “No module named context_processors”
    初识Vue——计算属性和观察者
    初识Vue——模板语法
    初识vue——起步
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/13638456.html
Copyright © 2011-2022 走看看