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

      首先抛开语言层面,简单介绍一下socket通信过程:

      1、服务器端开启监听端口,阻塞进程  等待客户端连接

      2、客户端连接,这时就产生了一个socket 

          socket就相当于一个传递消息的通道,一般都是成对出现的;客户端一个socket   服务器端一个socket,并且是由对应关系的;

          Java中,socket有两个属性比较重要:getInputStream与getOutputStream   分别用于读取对方传来的消息和发送消息

      OK,下面结合代码,介绍socket如何实现通信的

      先看服务器端代码:

    package test;
    import java.io.*;
    import java.net.*;
    public class helloWorld {
        public static void main(String[] args)
        {
            System.out.println("Hello Server!!");
            
            try{
                    ServerSocket server=null;
                    try
                    {
                        server=new ServerSocket(4700);
                        //创建一个ServerSocket在端口4700监听客户请求
                    }
                    catch(Exception e) 
                    {
                        System.out.println("can not listen to:"+e);
                        //出错,打印出错信息
                    }
                    Socket socket=null;
                    try{
                        socket=server.accept();
                        //使用accept()阻塞等待客户请求,有客户
                        //请求到来则产生一个Socket对象,并继续执行
                    }catch(Exception e) 
                    {
                        System.out.println("Error." + e);
                        //出错,打印出错信息
                    }
                    String line;
                    BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    //由Socket对象得到输入流,并构造相应的BufferedReader对象
                    PrintWriter os=new PrintWriter(socket.getOutputStream());
                    //由Socket对象得到输出流,并构造PrintWriter对象
                    BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
                    //由系统标准输入设备构造BufferedReader对象
                    System.out.println("Client:"+is.readLine());
                    //在标准输出上打印从客户端读入的字符串
                    line=sin.readLine();
                    //从标准输入读入一字符串
                    while(!line.equals("bye")){
                        //如果该字符串为 "bye",则停止循环
                        os.println(line);
                        //向客户端输出该字符串
                        os.flush();
                        //刷新输出流,使Client马上收到该字符串
                        System.out.println("Server:"+line);
                        //在系统标准输出上打印读入的字符串
                        System.out.println("Client:"+is.readLine());
                        //从Client读入一字符串,并打印到标准输出上
                        line=sin.readLine();
                        //从系统标准输入读入一字符串
                    }    //继续循环
                    os.close(); //关闭Socket输出流
                    is.close(); //关闭Socket输入流
                    socket.close(); //关闭Socket
                    server.close(); //关闭ServerSocket
                }
            catch(Exception e) 
            {
                System.out.println("Error." + e);
                //出错,打印出错信息
            }
        }
    
        }
    服务器端代码

      关键流程介绍:

      开启主机监听端口

    ServerSocket server=null;
    try
    {
          server=new ServerSocket(4700);
          //创建一个ServerSocket在端口4700监听客户请求
    }
    catch(Exception e) 
    {
          System.out.println("can not listen to:"+e);
          //出错,打印出错信息
    }

      阻塞线程,等待客户端连接,如果客户端连接,则会在服务器端产生一个socket 对象,通信会用到;

    Socket socket=null;
    try
    {
        socket=server.accept();
        //使用accept()阻塞等待客户请求,有客户
        //请求到来则产生一个Socket对象,并继续执行
    }catch(Exception e) 
    {
        System.out.println("Error." + e);
        //出错,打印出错信息
    }

      好,到此为止已经建立起通信通道,下面就说怎么发送与接收消息

      之前提到过socket有两个重要的属性getInputStream()  与getOutputStream(),本质上就是通过调用这两个属性的方法,来收发消息的;但是为了提高效率 需要将getInputStream()交给BufferedReader类处理  至于PrintWriter,向指定地方写入数据,暂时就是这么理解的。;不过,这样做有时候会出现一些问题,曾经做过一个接口,向服务器端发送消息,如果直接调用 InputStream 与 OutputStream方法,不会有任何问题,但是如果交由这些类去处理,就会有问题。原因大概是与服务器不匹配吧。

    BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream())); //将socket.getInputStream() 交给BufferedReader处理
    is.readLine()  // 这句话会从socket对象的输入流(即外部发送来的数据)读取数据,会阻塞线程

      下面这三句话句话,是用来向输出流中写入数据的

    PrintWriter os=new PrintWriter(socket.getOutputStream());
    os.println(readline);  //将数据写入缓冲区
    os.flush();            //强制将缓冲区中的数据输出(一般的话都是缓冲区满了之后 才输出)

      执行完这三句话后,就像对方发送数据了。

      OK,就先写到这儿了!

      下面将客户端代码贴上

      

    package testSocketClient;
    import java.net.*;
    import java.io.*;
    public class client 
    {
        public static void main(String[] args)
        {
            System.out.println("Hello Client!!");
            
            try
            {
                Socket socket=new Socket("127.0.0.1",4700);
                BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
                PrintWriter os=new PrintWriter(socket.getOutputStream());
                BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String readline;
                readline=sin.readLine(); //从系统标准输入读入一字符串
                readline = "nihao,good bye";
                while(!readline.equals("bye"))
                {
                    os.println(readline);
                    os.flush();
                    System.out.println("Client:"+readline);
                    System.out.println("Server:"+is.readLine());
                    readline=sin.readLine(); 
                }
                os.close(); //关闭Socket输出流
                is.close(); //关闭Socket输入流
                socket.close(); //关闭Socket
            }
            catch(Exception e)
            {
                System.out.println("错误信息:" + e);
            }
        }
        
    }
    View Code
  • 相关阅读:
    动态规划突破
    日志如何进行处理
    多线程相关问题
    Activity工作流框架
    修改模块
    spring多模块搭建Eureka服务器端
    springcould多模块搭建Eureka的服务器端口
    java操作elecsearch
    在elementui和MyBatis中前后端分离中使用shiro
    elementui的和前后端分离的微信登陆功能
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/4745384.html
Copyright © 2011-2022 走看看