• Socket编程实现客户端与服务器一对一聊天


    Socket(套接字)

    使用Socket编程实现数据的交互需要经历以下几个步骤:

      1、创建Socket:

           Socket socket = new Socket("host",port);

      2、打开IO流

    PrintWriter out = new PrintWriter(socket.getOutputStream(),true);//输出流
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))//输入流
    注: socket属于服务器,那么socket的方法getOutputStream就是向客户端输出数据,getInputStream获取客户端传过来的数据
    3、进行数据的交互
    out.print() in.read();
    4、关闭Socket
    socket.close();
    服务端跟客户端有所不同,客户端只要创建socket并且请求服务器连接connect,服务器创建完socket使用ServerSocket.accept()方法
    阻塞程序直到收到了来自客户端的请求,接收到来自客户端的socket继续往下执行。

    其中客户端代码如下:
    import java.net.*;
    import java.io.*;
    public class Client
    {
    
        boolean flag = false;//当遇到客户端输入bye取消与服务端连接的标识
    
        public Client(){
            try{
                Socket socket =new Socket("127.0.0.1",4800);//(host,port)
                System.out.println("客户端已经开启----");
                new Thread(new Output(socket)).start();
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获取来自服务端的信息
    
                String str = in.readLine();//读取信息
                while(!str.equals("bye")) {
                    System.out.println("服务端:"+str);
                    str = in.readLine();//当in每次调用readLine方法就会往下读取一行,慎用
                }
                in.close();
    
                if (flag==true){
                    socket.close();
                }
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    //当客户端没有写入信息的时候需要写一个线程来实现写操作,不然程序就会被卡在readLine一直获取键盘信息
        class Output implements Runnable{
            Socket socket;
            public Output(Socket socket){
                this.socket = socket;
            }
            public void run(){
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                try {
    
                    PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
    
                    String str = br.readLine();
                    while(!str.equals("bye")) {
                        System.out.println("客户端:"+str);
                        out.print(str+"
    ");//从键盘没有获取到回车按键,需要加
    判断一次输入为一行
                        out.flush();
                        str = br.readLine();
                        if (str.equals("bye")) {
                            flag = true;
                        }
                    }
                    br.close();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args)
        {
            new Client();
        }
    }
    

      服务端代码如下:

    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Server {
    
        boolean flag = false;
    
       public Server(){
           try {
               ServerSocket serverSocket = new ServerSocket(4800);
               System.out.println("服务端正在等待客户端请求......");
               Socket socket = serverSocket.accept();//一直等待客户端的请求
               System.out.println("connect success");
               new Thread(new Output(socket)).start();
               BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
              /* int i = 0;
               while ((i = in.read()) != 0){
                   System.out.println(i);
               }*/
               String str = in.readLine();
               while(!str.equals("bye")) {
                   System.out.println("客户端:" + str);
                   str = in.readLine();
               }
               in.close();
    
               if (flag==true) {
                   socket.close();
                   serverSocket.close();
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
    
       class Output implements Runnable{
          Socket socket;
          public Output(Socket socket){
              this.socket = socket;
          }
           public void run(){
               BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
               try {
                   PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
                   String str = br.readLine();
                   while(!str.equals("bye")) {
                       System.out.println("服务端:"+str);
                       out.print(str+"
    ");
                       out.flush();
                       str = br.readLine();
                       if (str.equals("bye")) {
                           flag = true;
                       }
                   }
                   br.close();
                   out.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
    
    
        public static void main(String[] args) {
            new Server();
        }
    }
    

      总结

                今天使用socket来实现客户端与服务端的通信功能,遇到了很多问题,其中一个比较严重的就是没有将写操作放入线程中进行,导致程序没有输出信息,第二个问题是当获取到从客户端/服务端来的信息时候,我是一行行的进行读取,但是没有读取到回车按键,无法区分一行的信息,导致客户端输入的信息,服务端无法接收,在朋友的debug下,使用了以下这个方法调试是否有数据传到另一边:

                int i = 0;
               while ((i = in.read()) != 0){
                   System.out.println(i);
    

    使用BufferReader的read方法返回的ASCII码,强转为int 可以直接获取原来的值(在ASCII范围内的值)。

  • 相关阅读:
    linux command lynx
    git bisect
    git blame (10)
    git crate&query&delete tag(九)
    git crate patch and check&apply patch(八)
    learning shell check host dependent pkg (8)
    【泛型】
    sql server 查询所有表的记录数
    【转】EXCEL中如何实现由总表自动得出分表
    MS Chart 打印
  • 原文地址:https://www.cnblogs.com/shigeng/p/8076263.html
Copyright © 2020-2023  润新知