• 示例:Socket应用之简易聊天室


    在实际应用中,Server总是在指定的端口上监听是否有Client请求,一旦监听到Client请求,Server就会启动一个线程来响应该请求,而Server本身在启动完线程之后马上又进入监听状态。

    示例:Socket应用之简易聊天室

    当一个Client连接Server之后,Server将向所有Client发送一个消息,这就需要Server和Client都一直处于监听状态。

    在Server,1. 通过一个List来存储所有连接进来的Socket 2. 为每个client开启了一个线程来响应请求。

    服务端程序

    public class Server {

      private static final int SERVER_PORT = 54321;

      private static List<Socket> mClientList = new ArrayList<Socket>();

      private ExecutorService mExecutorService;

      private ServerSocket mServerSocket;

      public Server () {

        try {

          mServerSocket = new ServerSocket(SERVER_PORT);

          mExecutorService = Executors.newCachedThreadPool();

          socket client = null;

          while(true) {

            client = mServerSocket.accept();

            mClientList.add(client);

            mExecutorService.execute(new ThreadServer(client));

          }

        } catch (IOException e) { }

      }

      // 为每个client独立开启一个线程。

      static class ThreadServer implements Runnable {

        private Socket mSocket;

        private BufferedReader mBufferedReader;

        private PrintWriter mPrintWriter;

        private String mStrMsg;

        public ThreadServer(Socket socket) throw IOException {

          mSocket = socket;

          mBufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream));

          mStrMsg = “user(”+mSocket.getInetAddress()+”) come, total client count: ” + mClientList.size();

          sendMessage();

        }

        public void run() {

          try {

            while((mStrMsg = mBufferedReader.readLine())!=null){

              if(mStrMsg.trim().equals(“exit”)) {

                // 当一个client退出时

                mClientList.remove(mSocket);

                mBufferedReader.close();

                mPrintWriter.close();

                mStrMsg = “user(”+mSocket.getInetAddress()+”) exit, total client count: ” + mClientList.size();

                mSocket.close();

                sendMessage();

                break;

              } else {

                mStrMsg = mSocket.getInetAddress() + “:”+ mStrMsg;

                sendMessage();

              } // else

            } // while

          }  catch(IOException e) { }

        }

        // 发送信息给所有client

        private void sendMessage() throws IOException {

          for(Socket socket : mClientList) {

            mPrintWriter = new PrintWriter(client.getOutputStream(), true);

            mPrintWriter.println(mStrMsg);

          }

        }

      }

    }

     

    客户端程序

    // android client app

    在onCreate方法中

    // 点击“登录”连接服务器

    mSocket = new Socket(SERVER_IP, SERVER_PORT);

    // 取得输入输出流

    mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));

    mPrintWriter = new PrintWriter(mSocket.getOutputStream(), true);

    // 点击“发送消息”

    String msg = mMsgBox.getText().toString();

    mPrintWriter.print(msg);

    mPrintWriter.flush();

    // 开启线程监听服务器发来的消息

    new Thread(mRunnable).start();

     

    // 监听Server发来消息的线程

    private Runnable mRunnable = new Runnable(){

      public void run() {

        while(true) {

          try {

            if((mStrMsg = mBufferedReader.readLine())!=null) {

              mStrMsg += “ ”;

              mHandler.sendMessage(mHandler.obtainMessage());

            }

          } catch(Exception e) { }

        }

      }

    };

     

    Handler mHandler = new Hander(){

      super.handleMessage(msg);

      try {

        mMsgLabel.append(mstrMsg);

      } catch(Exception e) { }

    }

  • 相关阅读:
    css自定义字体
    nuxt按需引入 element-UI、自定义主题色(终极按需引入)
    Vue 拖拽组件 vuedraggable 和 awe-dnd
    css 0.5px
    react取消监听scroll事件
    vue使用jsonp
    nuxt使用QRCode.js 生成二维码
    阻止冒泡
    nuxt.js配置BASE_URL(基本域名)和NODE_ENV(环境变量)
    Numpy基础学习笔记1
  • 原文地址:https://www.cnblogs.com/fengzhblog/p/3185493.html
Copyright © 2020-2023  润新知