首页 > 编程 > Java > 正文

java实现小型局域网群聊功能(C/S模式)

2019-11-26 13:56:14
字体:
来源:转载
供稿:网友

本文实例为大家分享了java群聊功能,供大家参考,具体内容如下

Java 对TCP协议的支持:
--> java.net包中定义了两个类ServerSocket 和Socket ,分别用来实现双向连接的server 端和client 端。 
--> Client 类定义客户端 

package com.dragon.java.tcpchat;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;/** * 客户端 *  * @author Auser *  */public class Client {  public static void main(String args[]) throws UnknownHostException,      IOException {    Socket client = new Socket("192.168.1.188", 10000);    // 穿件发送信息的线程    new ClientSend(client).start();    // 创建接收信息的线程    new ClientReceive(client).start();     // 因为要实现聊天功能,而不是只发送一次信息,所以输出流和客户端都不能关闭。    // client.shutdownOutput();    // client.close();  }}

--> ClientSend 类 定义客户端向服务端发送信息的线程 

package com.dragon.java.tcpchat;import java.io.IOException;import java.io.PrintStream;import java.net.Socket;import java.util.Scanner;/** * 客户端向服务端发送信息的线程 *  * @author Auser *  */public class ClientSend extends Thread {  private Scanner scanner;  private Socket socket;  public ClientSend(Socket socket) {    this.socket = socket;  }  @Override  public void run() {    scanner = new Scanner(System.in);    try {      PrintStream ps = new PrintStream(socket.getOutputStream());      String line = "";      // 阻塞式发送信息      while ((line = scanner.nextLine()) != null) {        ps.println(line);      }    } catch (IOException e) {      e.printStackTrace();    }  }}

--> ClientReceive 类 定义客户端接收服务端信息的线程 

package com.dragon.java.tcpchat;import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.Socket;/** * 客户端接收信息的线程 *  * @author Auser *  */public class ClientReceive extends Thread {  private Socket socket;  public ClientReceive(Socket socket) {    this.socket = socket;  }  @Override  public void run() {    try {      BufferedReader br = new BufferedReader(new InputStreamReader(          socket.getInputStream()));      // 按行接收信息      String line = "";      while ((line = br.readLine()) != null) {        System.out.println(line);      }    } catch (Exception e) {      e.printStackTrace();    }  }}

--> Server 类定义服务端 

package com.dragon.java.tcpchat;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;/** * 服务器 *  * @author Auser *  */public class Server {  public static void main(String[] args) throws IOException,      InterruptedException {    List<Socket> list = new ArrayList<>();    // 创建服务器端的套接字    ServerSocket server = new ServerSocket(10000);    while (true) {      // 接收客户端的阻塞方法      Socket socket = server.accept();      // 设计到多个线程可能会对集合进行增删的操作,要进行同步的处理      synchronized (list) {        list.add(socket);      }      // 启动一个新的线程去处理这个客户端的交流      new HandleSocket(socket, list).start();    }     // 因为不知道客户端什么时候发送信息,所以服务端要一直开启不能关闭。  }}

--> HandleSocket 类对连接到服务端的客户端进行操作(上下线通知、屏蔽拉黑、将信息发送到每个客户端等...) 

package com.dragon.java.tcpchat;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.InetAddress;import java.net.Socket;import java.util.List;/** * 处理每个(单个)连接到服务器的客户端的线程 *  * @author Auser *  */public class HandleSocket extends Thread {  private Socket socket;  private List<Socket> list;  /**   * 构造方法   *    * @param socket   *      当前连接的客户端   * @param list   *      存储已连接客户端的集合   */  public HandleSocket(Socket socket, List<Socket> list) {    this.socket = socket;    this.list = list;  }  /**   * 线程run方法   */  @Override  public void run() {    InetAddress address = socket.getInetAddress(); // 获取连接到服务器的这的客户端的地址    String ip = address.getHostAddress();    System.out.println(ip + "上线了!");    if (ip.equals("192.168.1.117")) {      synchronized (list) {        sendToAll(ip + "由于违规操作,已被拉入黑名单!");        list.remove(socket);      }      return;    }    try {      BufferedReader br = new BufferedReader(new InputStreamReader(          socket.getInputStream(), "gbk"));      String line = "";      while ((line = br.readLine()) != null) {        String msg = ip + ":" + line;        System.out.println(msg); // 输出到服务器端的控制台        // 把这个客户端说的话,发给其他所有的客户端        sendToAll(msg);      }    } catch (IOException e) {      // e.printStackTrace();      System.out.println(ip + "下线了!");      synchronized (list) {        list.remove(socket);      }    }  }  /**   * 把信息发送给所有的客户端,去除当前socket   *    * @param msg   *      发送的信息   */  private void sendToAll(String msg) {    synchronized (list) {      for (Socket s : list) {        if (s != socket) {          try {            PrintStream ps = new PrintStream(s.getOutputStream());            ps.println();          } catch (IOException e) {            e.printStackTrace();          }        }      }    }  }}

--> 注意:因为要实现客户端连接到服务端,即客户端要先找到服务端,所以服务端要先开启,再开启服务端...

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表