zoukankan      html  css  js  c++  java
  • JAVASE02-Unit011: TCP通信(小程序)

        TCP通信(小程序)    

    server端:

    package chat;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 聊天室服务端
     * @author adminitartor
     *
     */
    public class Server {
        /*
         * 运行在服务端的ServerSocket,主要作用:
         * 1:向操作系统申请服务端口,客户端就是通过
         *   这个端口与服务端程序建立连接的
         * 2:监听服务端口,一旦客户端连接了,就会创建
         *   一个Socket以便与该客户端交互  
         */
        private ServerSocket server;
        /*
         * 该集合存放所有客户端的输出流,以便于广播
         * 消息给所有客户端
         */
        private List<PrintWriter> allOut;
        
        /**
         * 构造方法,用来初始化服务端
         * @throws Exception
         */
        public Server() throws Exception{
            /*
             * 初始化,并申请服务端口,若该端口被
             * 其他应用程序占用,这里会抛出异常
             */
            server = new ServerSocket(8088);
            
            allOut = new ArrayList<PrintWriter>();
            
        }
        /**
         * 广播消息
         * @param message
         */
        public void sendMessage(String message){
            synchronized (allOut) {
                for(PrintWriter out : allOut){
                    out.println(message);
                }
            }
        }
        
        public void start(){
            try {
                /*
                 * ServerSocket提供方法:
                 * Socket accept() 
                 * 该方法是一个阻塞方法,直到一个客户端
                 * 通过申请的端口连接上,这里才会返回
                 * 返回的是一个Socket实例,通过该实例
                 * 即可与刚连接的客户端交互。
                 */
                while(true){
                    System.out.println("等待客户端连接...");
                    Socket socket = server.accept();
                    System.out.println("一个客户端连接了!");
                    /*
                     * 当一个客户端连接后,启动一个线程来处理
                     * 该客户端的交互工作。
                     */
                    ClientHandler handler
                        = new ClientHandler(socket);
                    Thread t = new Thread(handler);
                    t.start();
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            try {
                Server server = new Server();
                server.start();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("服务端运行失败!");
            }
        }
        
        /**
         * 该线程的任务是用来与指定的客户端进行
         * 交互
         * @author adminitartor
         *
         */
        private class ClientHandler 
                        implements Runnable{
            //当前线程通过该Socket与客户端交互
            private Socket socket;
            
            //该客户端的IP地址信息
            private String host;
            
            //该客户端的昵称
            private String nickName;
            
            public ClientHandler(Socket socket){
                this.socket = socket;
                /*
                 * 通过Socket获取远端计算机的地址
                 * 信息
                 */
                InetAddress address
                    = socket.getInetAddress();
                //获取ip地址信息
                host = address.getHostAddress();
            } 
            
            public void run(){
                PrintWriter pw = null;
                try {
                    /*
                     * Socket提供了方法:
                     * InputStream getInputStream()
                     * 该方法可以获取一个输入流,通过该流
                     * 读取到的内容就是远端计算机发送过来的数据
                     */
                    InputStream in
                        = socket.getInputStream();
                    
                    InputStreamReader isr
                        = new InputStreamReader(in,"UTF-8");
                    
                    BufferedReader br
                        = new BufferedReader(isr);
                    
                    /*
                     * 首先单独读取一行字符串,该字符串为
                     * 当前客户端的昵称
                     */
                    nickName = br.readLine();
                    
                    
                    /*
                     * 通过Socket获取输出流,以便将消息发送
                     * 给客户端
                     */
                    pw = new PrintWriter(
                        new OutputStreamWriter(
                            socket.getOutputStream(),
                            "UTF-8"
                        ),true    
                    );
                    /*
                     * 将当前客户端的输出流存入共享集合
                     */
                    synchronized (allOut) {
                        allOut.add(pw);
                    }        
                    
                    //广播当前用户上线
                    sendMessage(nickName+"上线了...");
                    
                    
                    
                    String message = null;
                    /*
                     * 读取客户端发送过来的消息时,当客户端断开连接
                     * 时,由于客户端系统不同,这里readLine方法的
                     * 执行结果也不同:
                     * 当windows的客户端断开后:这里会抛出异常
                     * 当linux的客户端断开后:这里会返回null
                     */
                    while((message = br.readLine())!=null){
    //                    System.out.println(host+"说:"+message);
    //                    //将消息发送给客户端
    //                    pw.println(host+"说:"+message);
                        //将消息广播给所有客户端
                        sendMessage(nickName+"说:"+message);
                    }
                    
                } catch (Exception e) {
                    
                } finally{
                    /*
                     * 处理客户端断开连接后的操作
                     */
                    //将该客户端的输出流从共享集合删除
                    synchronized (allOut) {
                        allOut.remove(pw);
                    }        
                    
                    
                    sendMessage(nickName+"下线了...");            
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                }
            }
        }
        
        
    }
    Server.java

    client端:

    package chat;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**
     * 聊天室客户端
     * @author adminitartor
     *
     */
    public class Client {
        /*
         * 封装了TCP通讯的Socket
         * 使用它可以与服务端建立连接,并进行通讯
         * 
         */
        private Socket socket;
        /**
         * 构造方法,用来初始化客户端
         */
        public Client() throws Exception{
            /*
             * 实例化Socket的过程就是连接服务端的
             * 过程。若连接失败,这里会抛出异常
             * 
             * 构造方法的两个参数:
             * 1:服务端计算机的IP地址
             * 2:服务端应用程序的端口
             */
            socket = new Socket(
                "localhost",8088    
            );
        }
        /**
         * 客户端开始工作的方法
         */
        public void start(){
            try {
                Scanner scanner = new Scanner(System.in);
                
                /*
                 *  先要求用户输入一个昵称:
                 */
                String nickName = null;
                
                while(true){
                    System.out.println("请输入您的昵称:");
                    nickName = scanner.nextLine().trim();
                    if(nickName.length()>0){
                        break;
                    }
                    System.out.println("请至少输入一个字符");
                }
                
                /*
                 * Socket提供了方法:
                 * OutputStream getOutputStream()
                 * 该方法会获取一个输出流,通过该输出
                 * 流写出的数据会发送给远端计算机。
                 */
                OutputStream out
                    = socket.getOutputStream();
                
                OutputStreamWriter osw
                    = new OutputStreamWriter(out,"UTF-8");
                
                PrintWriter pw 
                    = new PrintWriter(osw,true);                    
                
                /*
                 * 输出流创建完毕后先单独将昵称
                 * 发送至服务端
                 */
                pw.println(nickName);
                
                /*
                 * 将读取服务端消息的线程启动起来
                 */
                ServerHandler handler
                    = new ServerHandler();
                Thread t = new Thread(handler);
                t.start();
                
                String message = null;
                while(true){
                    message = scanner.nextLine();
                    pw.println(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            try {
                Client client = new Client();
                client.start();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("客户端运行失败!");
            }
        }
        /**
         * 该线程负责接收服务端发送过来的消息并
         * 输出到客户端的控制台。
         * @author adminitartor
         *
         */
        private class ServerHandler 
                            implements Runnable{
            public void run(){
                try {
                    BufferedReader br = new BufferedReader(
                        new InputStreamReader(
                            socket.getInputStream(),"UTF-8"    
                        )
                    );
                    String message = null;
                    while((message = br.readLine())!=null){
                        System.out.println(message);
                    }
                } catch (Exception e) {
                    
                }
            }
        }
        
    }
    Client.java
  • 相关阅读:
    实验十四 团队项目评审&个人学习总结
    实验四 附加实验项目互评
    201671010401 包稚潼+《英文文本统计分析》结队项目报告
    201671010401包稚潼 实验二 词频统计软件项目报告
    201671010401包稚潼 实验三作业互评与改进
    阅读《构建之法》提出的相关问题
    201671010404+陈润菊 实验十四 团队项目评审课程&学习总结
    201671010404+陈润菊 实验四 附加作业-项目互评
    201671010404+陈润菊 实验四《英文文本统计分析》结对项目报告
    201671010404+陈润菊 实验二软件工程项目
  • 原文地址:https://www.cnblogs.com/tangshengwei/p/6266777.html
Copyright © 2011-2022 走看看