java聊天室代码

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import java.util.StringTokenizer;

public class ChatClient {
 // 创建一个Socket
 private static Socket client = null;
 // 定义输入流变量
 private static DataInputStream di = null;
 // 定义输出流变量
 private static DataOutputStream dos = null;
 // 创建scanner对象接收数据
 Scanner sc = new Scanner(System.in);
 // 定义一个String变量保存用户名
 static String name;
 // 定义一个布尔值来判断是否循环接受用户名
 boolean falg = true;

 public static void main(String args[]) {
  // 创建对象
  ChatClient cc = new ChatClient();
  // 创建客户端的socket对象
  client = new Socket();
  // 调用方法
  cc.connect();
  // 调用方法
  cc.send();
 }

 // 连接
 public void connect() {

  // 创建客户端的socket对象
  client = new Socket();
  // 定义一个String接收IP地址
  String IP = null;
  // 定义一个int端口号
  int port = 0;
  System.out.println("***!!Welcome!!***");
  try {
   System.out.println("输入服务器的默认地址是0或127.0.0.1");
   // 接收一个IP保存到string对象中
   IP = sc.nextLine();
   // 匹配接收到的IP,接收到后将IP赋值为默认
   if (IP.equalsIgnoreCase("0")) {
    IP = "";
   }
 //设置端口号
   port = 8000;   
  } catch (Exception e) {
  }
  try {
   // 从给定的主机名得到ip存入inetaddress对象中
   InetAddress address = InetAddress.getByName(IP);
   // 根据得到的ip和端口号创建套接字地址
   InetSocketAddress socketaddress = new InetSocketAddress(address,
     port);
   // 将客户端的套接字链接到服务器
   try {
    // 连接服务器与客户端
    client.connect(socketaddress);
    // 判断是否有连接
    if (client.isConnected()) {
     // 调用方法
     runn();
    } else {
     client.connect(socketaddress);
     // 调用方法
     connect();
    }
   } catch (SocketException e) {
    System.out.println("不能连接到服务器,请重新输入");
    // 调用connect()重新连接
    connect();
   }
  } catch (Exception e) {
   System.out.println("不能连接到服务器,请重新输入");
   // 调用connect()重新连接
   connect();
  }

 }

 public void runn() {
  try {

   // 定义read对象
   ClientThread read = null;
   // 创建read对象
   read = new ClientThread();
   // 创建readdata线程对象
   Thread readData = new Thread(read);
   // 封装一个DataInputStream对象得到输入流

   di = new DataInputStream(client.getInputStream());
   // 封装一个DataOutputStream对象得到输出流
   dos = new DataOutputStream(client.getOutputStream());
   // 接受用户名
   while (falg) {
    System.out.println("请输入用户名:");
    name = sc.next();
    System.out.println(name + "上线了");
    System.out.println("欢迎进入聊天室,需要帮助请输入/A");
    dos.writeUTF(name);
    dos.flush();
    read.setDataInputStream(di);
    // 启动线程
    readData.start();
    // 改变flag中断循环
    falg = false;
   }
  } catch (IOException e) {

  }

 }

 // 写入信息
 @SuppressWarnings("deprecation")
 public void send() {
  // 循环接收发送的消息
  System.out.println("请输入内容:");
  while (sc.hasNext()) {
   String mess;
   mess = sc.nextLine();
   if (mess.equalsIgnoreCase("/0")) {
    System.exit(0);
   } else if (mess.equalsIgnoreCase("/D")) {
    try {
     File file = new File("qq.txt");
     di = new DataInputStream(new FileInputStream(file));
     String info = null;
     System.out.println("1 微笑;2 哭泣;3 疑问;4 加油;5 喔耶~;");
     System.out.println("6 幸福;7 好冷;8 刺眼;9 昏倒;10 幸福;");
     System.out.println("请选择表情:");
     String age = sc.next();
     while ((info = di.readLine()) != null) {
      StringTokenizer stri = new StringTokenizer(info, ".");
      String inn = stri.nextToken();
      String in = stri.nextToken();
      // System.out.println(in);

      if (age.equals(inn)) {
       dos.writeUTF(in);
       break;
      }
     }
    } catch (Exception e) {
    }

   }
   if (mess.equals("/D")) {

   } else {
    select(mess);
   }

  }
 }

 // 将消息发送给服务器
 public void select(String mess) {
  // 判断输入的信息
  if (mess.equalsIgnoreCase("/A")) {
   // 匹配上调用helpList()方法
   helpList();
  } else if (mess.equalsIgnoreCase("/C")) {
   try {
    System.out.println("请输入你要查看的聊天记录的名字");
    String str1 = sc.next();
    File file = new File(str1 + ".txt");
    BufferedReader bf = new BufferedReader(new FileReader(file));
    String str = null;
    while ((str = bf.readLine()) != null) {
     System.out.println(str);
    }
    bf.close();
   } catch (IOException e) {

   }

  } else {
   try {
    // 将消息发送给服务器
    dos.writeUTF(mess);
    // 清空输出流
    dos.flush();
   } catch (IOException e) {

   }
  }
 }

 public void helpList() {

  System.out.println("提示:进入聊天室,默认公聊!!");
  System.out.println("/B 用户在线列表,用户/信息 私聊,/C 查看聊天记录,/D 发送表情,/0 退出系统");
 }
}

 

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;


public class ClientThread implements Runnable {
 // 定义一个DataInputStream变量
 DataInputStream di;
 // 定义一个string对象接收服务器发送的消息
 String str;
 boolean ff=true;

 public void setDataInputStream(DataInputStream di) {
  this.di = di;
 }

 public void run() {
  while (true) {
   try {
    // 从流中读取信息
    str = di.readUTF();
    // 调用writeFile将信息写入文件中
    writeFile(str);
    // 显示信息
    System.out.println(str);
    
   } catch (IOException e) {
    // 服务器断开后客户端显示提示信息
    System.out.println("服务断开~~~~~~~");
    // 终止客户端
    System.exit(0);
   }
  }
 }
 
 public void writeFile(String str2) {
  try {
   // 创建一个文件
   File file = new File(ChatClient.name + ".txt");
   FileWriter fw = new FileWriter(file, true);
   BufferedWriter bw = new BufferedWriter(fw);
   bw.write(str2);
   // 写入一个行分隔符
   bw.newLine();
   // 关闭缓冲流
   bw.close();
   // 关闭字符输出流
   fw.close();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

 

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;

public class ServerThread implements Runnable {
 // 定义一个socket变量
 Socket client = null;
 // 定义一个Datainputstream变量
 DataInputStream di = null;
 // 定义一个Dataoutputstream变量
 DataOutputStream dos = null;
 // 定义一个变量保存连接当前线程的用户名
 String name = null;
 // 创建一个hashtable对象用来保存所有的为客户端开辟的线程对象
 static Hashtable<String, ServerThread> clientlist = new Hashtable<String, ServerThread>();

 public ServerThread() {
 }

 public ServerThread(Socket client, String name) {
  try {
   // 将传入的client赋值给成员变量的client
   this.client = client;
   // 将传入的name赋值给成员变量的name
   this.name = name;
   // 将服务器的输出流封装到DataInputStream中
   di = new DataInputStream(client.getInputStream());
   // 将服务器的输出流封装到DataOutputStream中
   dos = new DataOutputStream(client.getOutputStream());
  } catch (IOException e) {
  }

 }

 public void run() {
  try {

   // 添加当前对象到hashtable
   clientlist.put(name, this);
   // 发送新用户进入的消息给所有客户端
   sendallClient(name + "进入聊天室");

   while (true) {

    // 定义一个string对象接受从流中读取到的信息
    String mess = di.readUTF();

    // 创建一个stringtokenizer对象分析接收到的消息
    StringTokenizer str = new StringTokenizer(mess, "/");
    // 判断截取到的信息有没分隔符
    // 如果有分隔符则判断为私聊发送信息
    if (str.countTokens() == 2) {
     // 得到要发送私聊信息用户的姓名
     String nameid = str.nextToken();
     // 得到要发送的私聊信息
     String message = str.nextToken();
     // 调用发sendclient送私聊信息
     sendClient(nameid, message);

     // 没有分隔符或者有多个分隔符是信息默认为公聊发送
    } else if (mess.equalsIgnoreCase("/B")) {
     // 匹配到调用getlist方法
     getList();
     // 判断信息是否与-change匹配
    } else if (mess.equalsIgnoreCase("/0")) {
     System.out.println("name" + "退出聊天室");
     break;
    } else if (str.countTokens() == 1 || str.countTokens() >= 3) {
     // 调用sendallclient发送公聊信息
     sendallClient(name + "说:" + mess);

    }

   }
   client.close();
  } catch (Exception e) {

  } finally {
   // 清除客户端信息
   clientlist.remove(name);
   File file=new File(name+".txt");
   //文件删除
   file.delete();
   // 有人退出时,给所有人发送退出信息
   sendallClient(name + "退出聊天室");
   System.out.println(getDate() + " " + name + "退出聊天室");
  }
 }

 // 公聊

 public void sendallClient(String mess) {
  // 获得clientlist中值得ServerThread放入枚举集合中
  Enumeration<ServerThread> allclients = clientlist.elements();
  // 遍历所有客户
  while (allclients.hasMoreElements()) {
   // 枚举中还有元素是,返回此举的下一个元素
   ServerThread st = (ServerThread) allclients.nextElement();
   try {
    // 将信息写入流中
    st.dos.writeUTF(getDate() + "\t" + mess);
    // 刷新流
    st.dos.flush();
   } catch (IOException e) {
    Thread th = new Thread(st);
    // 产生异常中断此线程
    th.interrupt();
    
   }
  }
 }

 // 私聊
 public void sendClient(String name1, String mess) {
  ServerThread st = clientlist.get(name1);
  ServerThread st1 = clientlist.get(name);
  try {
   // 将要发送的信息保存到流中
   st.dos.writeUTF(getDate() + "\t" + name + "对你说:\t" + mess);
   // 刷新流
   st.dos.flush();

   // 把信息发给原客户端
   st1.dos.writeUTF(getDate() + "\t你对" + name1 + "说:\t" + mess);
   // 刷新流
   st1.dos.flush();
  } catch (IOException e) {

   System.out.println("你发送的信息有误,请重新发送!");
   sendClient(name1, mess);
  }
 }

 

 public boolean checkp(String str) {
  boolean flag = true;
  // 得到所有的用户名
  Enumeration<String> checkname = clientlist.keys();
  // 循环检查用户名
  while (checkname.hasMoreElements()) {
   // 枚举中还有元素是,返回此举的下一个元素
   String sn = (String) checkname.nextElement();
   // 判断用户名是否重复,重复的话返回false
   if (str.equalsIgnoreCase(sn)) {
    // 返回false
    flag = false;
    // 判断用户名是否为空
   } else if (str.equalsIgnoreCase("")) {
    // 返回false
    flag = false;
   }
  }
  return flag;
 }

 // 关闭服务器
 public void guanBi() {
  if (!(client == null)) {
   try {
    client.close();
    System.out.println("客户端退出此系统");
   } catch (IOException e) {

   }

  }
 }

 // 显示用户在线
 public void getList() {
  // 获得所有键的枚举
  Enumeration<String> checkname = clientlist.keys();
  // 通过用户名获得线程对象
  ServerThread st = clientlist.get(name);
  try {
   // 写入信息
   st.dos.writeUTF("在线用户列表");
   // 写入用户在线人数
   st.dos.writeUTF(clientlist.size() + ":人在线");
  } catch (IOException e1) {

   e1.printStackTrace();
  }
  // 便利枚举
  while (checkname.hasMoreElements()) {
   // 枚举中还有元素是,返回此举的下一个元素
   String sn = (String) checkname.nextElement();
   try {
    // 将用户信息写入流中
    st.dos.writeUTF("用户名称:" + sn);
    // 清空输出流
    st.dos.flush();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 // 时间
 public String getDate() {
  // 获得data对象
  Date nowTime = new Date();
  // 创建格式化参数
  String pattern = "HH:mm:ss";
  // 创建SimpleDateFormat对象
  SimpleDateFormat sdf = new SimpleDateFormat(pattern);
  // 定义一个变量接收时间
  String timePattern = sdf.format(nowTime);
  // 返回当前时间
  return timePattern;
 }

}

 

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {
 // 定义一个serversocket对象
 private static ServerSocket server = null;
 // 定义一个socket对象
 private static Socket client = null;
 // 定义一个变量用来保存客户端的用户名
 private static String name;
 // 定义一个布尔值变量
 private static boolean falg = true;
 // 定义输入流变量
 private static DataInputStream di = null;
 // 定义输出流变量
 private static DataOutputStream dos = null;

 public static void main(String args[]) {
  // 创建ServerThread对象
  ServerThread st = new ServerThread();
  while (true) {
   try {

    // 创建serversocket对象指定端口号为8000
    server = new ServerSocket(8000);
   } catch (IOException e) {
    System.out.println("正在监听!!");
   }
   try {
    System.out.println("等待客户端连接....");
    // 将客户端的套接字与服务器的套接字连接起来
    client = server.accept();
    System.out.println("连接成功!!");
    // 将服务器的输入流封装到DataInputStream中
    di = new DataInputStream(client.getInputStream());
    // 将服务器的输出流封装到DataInputStream中
    dos = new DataOutputStream(client.getOutputStream());
    // 从流中读取用户名
    while (falg) {
     name = di.readUTF();
     if (st.checkp(name)) {
      System.out.println("客户的地址:" + client.getInetAddress()
        + "\t" + name + ":进入聊天室");
      // 将falg变为false
      falg = false;
     } else {
      // 清空输出流
      dos.flush();
     }
    }
   } catch (IOException e) {
    System.out.println("正在等待客户端呼叫......");
   }

   // 判断是否有客户端连接到服务器
   if (client.isConnected()) {
    // 创建服务器端的收发信息线程对象
    ServerThread sth = new ServerThread(client, name);
    Thread th = new Thread(sth);
    // 启动线程
    th.start();
    falg = true;
   }
  }
 }
}

转载于:https://my.oschina.net/u/778577/blog/78584

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值