zoukankan      html  css  js  c++  java
  • java的socket通信

        本文讲解如何用java实现网络通信,是一个非常简单的例子,我比较喜欢能够立马看到结果,所以先上代码再讲解具体细节。

    服务端

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
        // 搭建服务器端
        public static void main(String[] args) throws IOException {
            Server server = new Server();
            //创建一个服务器,即Server
            server.oneServer();
        }
    
        public void oneServer() {
            try {
                ServerSocket server = null;
                server = new ServerSocket(5209);
                System.out.println("服务器启动成功");
                System.out.println("等待客户端连接");
                // 指定绑定的端口,并监听此端口。
                
                Socket socket = server.accept();
                System.out.println("监听到客户端的连接");
                System.out.println("连接成功");
                //调用accept()方法开始监听端口,等待客户端的连接
                
                
                String line;
                //存储对方传过来的数据
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 从socket对象中取出对方传过来的数据
    
                 PrintWriter writer=new PrintWriter(socket.getOutputStream());
                // 向socket总写如要传给对方的数据
    
                while ((line = in.readLine()) != null) {
                     writer.println(line+" deal by servet");
                    // 向客户端输出该字符串
                     writer.flush();
                    // 刷新输出流,使Client马上收到该字符串
                    System.out.println("Client:" + line);
                    // 从Client读入一字符串,并打印到标准输出上
                } // 继续循环
    
                // 关闭资源
                writer.close(); //关闭Socket输出流
                in.close(); // 关闭Socket输入流
                socket.close(); // 关闭Socket
                server.close(); // 关闭server
            } catch (Exception e) {// 出错,打印出错信息
                System.out.println("Error." + e);
            }
        }
    }

    客户端

    import java.net.Socket;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.URL;
    
    public class Client {
        // 搭建客户端
        public static void main(String[] args) throws IOException {
            try {
                // 创建客户端Socket,指定服务器地址和端口
                // Socket socket=new Socket("127.0.0.1",5200);
                System.out.println("客户端启动成功");
                Socket socket = new Socket("192.168.69.183", 5209);
                System.out.println("向服务端5209端口请求成功");
                
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                // 由系统标准输入设备读入数据,该数据通过writer写到对方的socket中
                
                PrintWriter write = new PrintWriter(socket.getOutputStream());
                // 向socket总写入要传给对方的数据
                
               BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 从socket对象中取出对方传过来的数据
                
                String readline;
                readline = br.readLine(); // 从系统标准输入读入一字符串
                while (!readline.equals("end")) {
                    // 若从标准输入读入的字符串为 "end"则停止循环
                    write.println(readline);
                    // 将从系统标准输入读入的字符串输出到对方的socket中
                    write.flush();
                    
                    //打印出对方传过来的数据
                    System.out.println("Server:" + in.readLine());
                    // 从Server读入一字符串,并打印到标准输出上
                    readline = br.readLine(); // 从系统标准输入读入一字符串
                } // 继续循环
                //关闭资源 
                write.close(); // 关闭Socket输出流
               // in.close(); // 关闭Socket输入流
                socket.close(); // 关闭Socket
                br.close();
            } catch (Exception e) {
                System.out.println("can not listen to:" + e);// 出错,打印出错信息
            }
        }
    
    }

      这里我们要实现的功能是客户端从键盘输入一个字符串,发送给服务端,服务端处理(原字符串后加上“deal by servet”)完成后返回给客户端。我用的是eclipse,最好开两个eclipse一个跑客户端一个跑服务端。先开服务端,再开客户端(顺序不能错),客户端输入hello,服务端返回hello deal by server:

      

      看到成果了那么可以分析一下整个通信过程。

      先放一个socket通信模型:

      

      

      三部分:建立连接,开始通信,断开连接

      建立连接:我们稍微思考一下就可以知道建立连接的过程要先存在服务端server,然后客户端client才能找,所以要先启动服务端。可能我们认为服务端或者说服务器是一个很神秘的东西,其实不是,看我们这个例子中服务端的代码:

      

      new一个服务器,但是这个服务器new出来之后什么都没做,我们需要调用他里面的方法让这个服务器可以运行。所以写了一个oneServer方法,服务器对象调用这个方法开始运行。

      那么服务器运行的时候都干了什么呢?看上面的模型,服务器运行做三件事:连接,传送数据,断开。

      看oneServer中的代码,先是创建了一个ServerSocket的对象,这个对象有一个参数5209:

      

      ServerSocket是专门用来创建服务器对象的,其中的参数5209表示这个服务器可以通过5209端口被客户端连接,即5209端口与创建的这个ServerSocket对象绑定了。但是这个绑定只是在服务器与端口之间建立了一个通道,我们还要能够让服务器知道有数据从外面到了这个端口,并且因为端口不能存放数据所以需要一个socket来暂时存放数据。所以有了下面的监听:

      

      

       到这里,服务器已经启动并运行了,客户端可以连接了。

      这时候启动客户端,客户端通过socket连接到服务端,指定ip和端口号:

      

      客户端运行到这里表示与服务端的连接已经完成

      

      

      连接成功之后就是传送数据,客户端创建三个对象:

      

      br从键盘读入要传送的数据,write向socket写入要传给服务端的数据,in从socket对象中取出服务端返回的数据。

      服务端创建两个对象:

      

      write向socket写入要传回给客户端的数据,in从socket对象中取出客户端传来的数据。

       到这里数据传输的准备工作完成,接下来就是数据传输。

      客户端从键盘读入一个字符串(hello),通过br读入:

      

      

      

      

      然后客户端判断是否为end,不是end就继续。通过客户端的write,将readline中的内容写到对方(服务端)的socket中,同时使用write的flush方法通知服务端,让服务端立马知道有数据了:

      

      服务端监听到端口有数据之后,通过in接收客户端发过来的数据,并转成字符串,然后处理这个字符串(加上deal by server)并写到客户端的socket中,同时也调用writer的flush方法通知客户端

      

      运行到这里,服务端已经处理并返回了客户端发过来的数据,在客户端的控制台中可以看到返回的数据:

      

      服务端在自己的控制台中打印出客户端发过来的数据:

      

      

      整个传送流程结束,如果输入的字符串是end,那么就会跳出while循环,客户端服务端各自关闭资源:

      

      

      到这里,整个过程结束。

      再文字说明一下整个流程,服务器启动——服务器创建socket并监听——客户端启动——客户端创建socket连接服务端——连接完成——客户端输入数据并写到服务端的socket传送给服务端——服务端接收到客户端传来的数据——对数据进行处理——处理完毕放到客户端的socket中——客户端拿取自己socket中的数据——打印——双方断开连接。

      

      

  • 相关阅读:
    HDU 4069 Squiggly Sudoku
    SPOJ 1771 Yet Another NQueen Problem
    POJ 3469 Dual Core CPU
    CF 118E Bertown roads
    URAL 1664 Pipeline Transportation
    POJ 3076 Sudoku
    UVA 10330 Power Transmission
    HDU 1426 Sudoku Killer
    POJ 3074 Sudoku
    HDU 3315 My Brute
  • 原文地址:https://www.cnblogs.com/GoForMyDream/p/8710162.html
Copyright © 2011-2022 走看看