zoukankan      html  css  js  c++  java
  • 网络编程+多线程实现简单的聊天室功能

    一:需求分析

    1:聊天室:一个服务器,多个客户端,当一个客户端发送信息给服务器时,服务器会把

    消息广播给其他的客户端用户。

    2:服务器端,主线程一直处于阻塞状态,接受客户端请求,每当一个客户端发送请求过来

    时,都会启动一个线程处理请求。

    3:客户端,主线程负责向服务器通过控制台写数据,另外启动一个线程负责读取服务器端发送

    过来的信息。

    二:服务器端

     1 /**
     2  * 
     3  */
     4 package com.hlcui.socket;
     5 
     6 import java.io.BufferedReader;
     7 import java.io.IOException;
     8 import java.io.InputStreamReader;
     9 import java.io.PrintWriter;
    10 import java.net.InetAddress;
    11 import java.net.ServerSocket;
    12 import java.net.Socket;
    13 import java.util.ArrayList;
    14 import java.util.Collections;
    15 import java.util.List;
    16 
    17 /**
    18  * @author Administrator
    19  * 
    20  */
    21 public class MyServer {
    22     public static final int PORT = 8080;
    23     public static List<Socket> socketList = Collections
    24             .synchronizedList(new ArrayList<Socket>()); // 定义一个线程安全的list
    25 
    26     // 初始化
    27     public void init() {
    28 
    29         try {
    30             ServerSocket ss = new ServerSocket(PORT);
    31             System.out.println("服务已经启动,等待客户端连接...");
    32             // 主线程一直在监听端口
    33             while (true) {
    34                 Socket s = ss.accept();
    35                 InetAddress inet = s.getInetAddress();
    36                 System.out.println(inet.getHostAddress()+"上线了");
    37                 socketList.add(s);
    38                 new Thread(new ServerThread(s)).start(); // 启动线程处理客户端请求
    39             }
    40         } catch (IOException e) {
    41             e.printStackTrace();
    42         }
    43     }
    44 
    45     public static void main(String[] args) {
    46         MyServer server = new MyServer();
    47         server.init();
    48     }
    49 }
    50 
    51 class ServerThread implements Runnable {
    52     private BufferedReader br;
    53     private Socket s;
    54 
    55     ServerThread(Socket s) throws IOException {
    56         this.s = s;
    57         br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    58     }
    59 
    60     @Override
    61     public void run() {
    62         String line = null;
    63         while ((line = readClientContext()) != null) {
    64             System.out.println(line);
    65             // 将客户端数据广播出去(传递给每个客户端数据)
    66             for (Socket s : MyServer.socketList) {
    67                 try {
    68                     PrintWriter pw = new PrintWriter(s.getOutputStream());
    69                     pw.println(line);
    70                     pw.flush();
    71                     //pw.close();  //这里的pw一定不能关闭
    72                 } catch (IOException e) {
    73                     e.printStackTrace();
    74                 }
    75             }
    76         }
    77     }
    78 
    79     // 读取客户端数据
    80     private String readClientContext() {
    81         try {
    82             return br.readLine();
    83         } catch (IOException e) {
    84             MyServer.socketList.remove(s);
    85             System.out.println("读取客户端数据失败!");
    86         }
    87         return null;
    88 
    89     }
    90 
    91 }

    三:客户端

     1 /**
     2  * 
     3  */
     4 package com.hlcui.socket;
     5 
     6 import java.io.BufferedReader;
     7 import java.io.IOException;
     8 import java.io.InputStreamReader;
     9 import java.io.PrintStream;
    10 import java.net.Socket;
    11 
    12 /**
    13  * @author Administrator
    14  * 
    15  */
    16 public class MyClient {
    17     public static final String IP = "127.0.0.1";
    18     public static final int PORT = 8080;
    19 
    20     // 初始化
    21     public void init() {
    22         BufferedReader br = null;
    23         PrintStream ps = null;
    24         try {
    25             Socket s = new Socket(IP, PORT);
    26             // 启动线程读取服务器端发送的数据
    27             new Thread(new ClientThread(s)).start();
    28             // 控制台向服务器发送数据
    29             br = new BufferedReader(new InputStreamReader(System.in));
    30             ps = new PrintStream(s.getOutputStream());
    31             String line = null;
    32             while ((line = br.readLine()) != null) {
    33                 ps.println(line);
    34             }
    35             ps.flush();
    36         } catch (IOException e) {
    37             e.printStackTrace();
    38         } finally {
    39             if (br != null) {
    40                 try {
    41                     br.close();
    42                 } catch (IOException e) {
    43                     e.printStackTrace();
    44                 }
    45             }
    46             if (ps != null) {
    47                 ps.close();
    48             }
    49         }
    50     }
    51 
    52     public static void main(String[] args) {
    53         MyClient client = new MyClient();
    54         client.init();
    55     }
    56 
    57 }
    58 
    59 class ClientThread implements Runnable {
    60     private BufferedReader br;
    61 
    62     ClientThread(Socket s) {
    63         try {
    64             br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    65         } catch (IOException e) {
    66             e.printStackTrace();
    67         }
    68     }
    69 
    70     @Override
    71     public void run() {
    72         String line = null;
    73         try {
    74             while ((line = br.readLine()) != null) {
    75                 System.out.println(line);
    76             }
    77         } catch (IOException e) {
    78             e.printStackTrace();
    79         }
    80     }
    81 
    82 }

     

  • 相关阅读:
    UIImagePickerController 获取相片视频
    plist文件Boolean类型读写方法
    stringstream 用法
    C++11中提供了std::bind
    图像的亮度和对比度调节
    windows C++ 全局异常捕捉函数
    windows 下多线程
    C++11 Lambda表达式(匿名函数)
    图像亮度调节--幂次变换
    SEH:结构化异常处理 学习
  • 原文地址:https://www.cnblogs.com/warrior4236/p/5683043.html
Copyright © 2011-2022 走看看