• Java TCP案例网络聊天室


    收获:1,加深了对多线程的一边一边的理解,可以将行为写成不同的类然后多线程

            2,IO流的复习!

            3,多线程中一边读取一边操作时容器最好(CopyOnWriteArrayList);

            4,Tcp流程的熟悉;

            5,封装!!!代码的复用以及整洁!!!

    改进:1,注释

               2,对其中更多内容的封装,比如消息等

    /**
     * 聊天室服务端
     * 实现接受和发送消息
     * 私聊
     * @author 小帆敲代码
     *
     */
    public class ChatServer {
     static CopyOnWriteArrayList<Channel> all=new CopyOnWriteArrayList();
     public static void main(String[] args) throws IOException {
      ServerSocket server=new ServerSocket(8888);
      while(true) {
      Socket client=server.accept();
      System.out.println("一个客户端已连接");
      //添加至系统容器
      Channel channel=new Channel(client);
      all.add(channel);
      new Thread(channel).start();
      }
     }
     static class Channel implements Runnable{
      private DataInputStream dis;
      private DataOutputStream dos;
      private boolean isRunning=true;
      private Socket client;
      private boolean isName;
      private String name;
      
      public Channel(Socket client) {
       isName=true;
       isRunning=true;
       this.client=client;
       try {
        dis=new DataInputStream(client.getInputStream());
        dos=new DataOutputStream(client.getOutputStream());
       } catch (IOException e) {
        release();
       }
      }
      //接受消息
      public String receive() {
       String msg="";
       try {
        msg=dis.readUTF();
       } catch (IOException e) {
        release();
       }
       return msg;
      }
      //发送消息
      public void send(String msg) {
       if(!msg.equals("")) {
        try {
         dos.writeUTF(msg);
         dos.flush();
        } catch (IOException e) {
         release();
        }
       }
      }
      //给别人发送消息
      public void sendOthers(String msg) {
       //私聊
       //获取名字和内容
       if(msg.startsWith("@"))
       {
       int idx=msg.indexOf(":");
       String othername=msg.substring(1, idx);
       msg=msg.substring(idx+1);
       for(Channel others:all) {
        if(others.getName().equals(othername))
         {
         others.send(this.name+"悄悄对你说:"+msg);
         break;
         }
       }
       }
       else if(!msg.equals("")) {
        for(Channel others:all) {
         if(others==this)
          this.send("我:"+msg);
         else
          others.send(this.name+":"+msg);
        }
       }
      }
      //释放资源
      public void release() {
       isRunning=false;
       Utils.close(dis,dos,client);
      }
      @Override
      public void run() {
       String msg;
       while(isRunning) {
        if(isName)
        {
         msg=receive();//读
         this.name=msg;
         isName=false;
        }
        else
        {
        msg=receive();//读
        sendOthers(msg);//写
        }
       }
       release();//释放资源
      }
      public String getName() {
       return this.name;
      }
    }
    }

    /**
     * 客户端
     *
     * @author 小帆敲代码
     *
     */
    public class ChatClient {
     public static void main(String[] args) throws UnknownHostException, IOException {
      Socket client=new Socket("localhost",8888);
      
      new Thread(new Send(client)).start();
      new Thread(new Receive(client)).start();
     }
    }
    /**
     * 接收类
     * @author 小帆敲代码
     *
     */
    public class Receive implements Runnable{
     private DataInputStream dis;
     private Socket client;
     private boolean isRunning;
     
     public Receive(Socket client) {
      isRunning=true;
      this.client=client;
      try {
       dis=new DataInputStream(client.getInputStream());
      } catch (IOException e) {
       System.out.println("==4==");
       release();
      }
     }
     private String receive() {
      try {
       return dis.readUTF();
      } catch (IOException e) {
       System.out.println("==5==");
       release();
      }
      return "";
     }
     @Override
     public void run() {
      while(isRunning) {
       String msg=receive();
       System.out.println(msg);
      }
      
     }
     public void release() {
      isRunning=false;
      Utils.close(dis,client);
     }
    }
    /**
     * 发送类
     * @author 小帆敲代码
     *
     */
    public class Send implements Runnable{
     private BufferedReader console;
     private DataOutputStream dos;
     private Socket client;
     private boolean isRunning;
     private String name;
     
     public Send(Socket client) {
      isRunning=true;
      this.client=client;
      console=new BufferedReader(new InputStreamReader(System.in));
      try {
       System.out.println("请输入用户名:");
       this.name=console.readLine();
       System.out.println(name+"欢迎回来");
       dos=new DataOutputStream(client.getOutputStream());
       this.send(name);
      } catch (IOException e) {
       System.out.println("==1==");
       release();
      }
     }
    /*
     * 约定格式:
     * 私聊:@xxx:msg
     */
     private void send(String msg) {
      if(msg!="") {
       try {
        dos.writeUTF(msg);
        dos.flush();
       } catch (IOException e) {
        System.out.println("==2==");
        release();
       }
      }
     }
     private String getStrFromConsole() {
      try {
       return console.readLine();
      } catch (IOException e) {
       System.out.println("==3==");
       release();
      }
      return "";
     }
     @Override
     public void run() {
      while(isRunning) {
       String msg=getStrFromConsole();
       send(msg);
      }
      
     }
     private void release() {
      isRunning=false;
      Utils.close(console,dos,client);
     }
    }
    /**
     * 工具类
     * @author 小帆敲代码
     *
     */
    public class Utils {
     /**
      *释放资源
      */
     static void close(Closeable... targets) {
      for(Closeable target:targets) {
       try {
        if(target!=null)
         target.close();
       }catch(Exception e){
        
       }
      }
     }
    }
  • 相关阅读:
    webstorm快捷键大全
    Js的reduce()方法
    利用 c# linq 实现多个数据库的联合查询
    微信小程序支付接入注意点
    ubuntu所有php扩展php-7.0扩展列表
    ubuntu 16.04 php 安装curl方法
    Ubuntu下配置Apache开启HTTPS
    Mac下如何用SSH连接远程Linux服务器及Linux一些常用操作命令,更新中.....
    Mac下如何用SSH连接远程Linux服务器
    C#的dapper使用
  • 原文地址:https://www.cnblogs.com/code-fun/p/11249868.html
Copyright © 2020-2023  润新知