JAVASE聊天室
客户端:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
import Clinet.untils.InputUtil;
import Configs.Configs;
public class ClientDemo {
private static OutputStream out;
private static InputStream in;
public static Scanner sc;
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 1008);
out = s.getOutputStream();
in = s.getInputStream();
sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您要注册的用户名:");
String username = sc.nextLine();
out.write(username.getBytes());
byte[] bys = new byte[1024];
int len = in.read(bys);
String msg = new String(bys, 0, len);
if (msg.equals("yes")) {
System.out.println(username + "登陆成功");
break;
} else {
System.out.println("该用户已存在,请重新输入用户名");
}
}
ClientThread ct = new ClientThread(in);
ct.start();
boolean flag =true ;
while (flag) {
System.out.println("请选择类型:1私聊,2公聊,3在线人数,4下线");
// 消息类型 消息对象:消息内容:消息类型
int num = InputUtil.inputIntType(new Scanner(System.in));
switch (num) {
case 1:
// 私聊
privateTalk();
break;
case 2:
// 公聊
publicTalk();
break;
case 3:
// 在线人数
System.out.println("当前在线人数....");
showTalker();
break;
case 4:
// 下线
downLine();
flag=false;
ct.flag=false;
break;
}
}
s.close();
} catch (SocketException e) {
} catch (IOException e) {
e.printStackTrace();
}finally {
}
}
private static void downLine() {
try {
String msg = "null" + ":" + "null" + ":" + Configs.MSG_EXIT;
out.write(msg.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
private static void showTalker() throws IOException {
while (true) {
String msg = "null"+":"+"null"+":"+Configs.MSG_ONLIST;
out.write(msg.getBytes());
break;
}
}
private static void publicTalk() {
System.out.println("当前处于公聊模式.....");
try {
while (true) {
String msg = sc.nextLine();
if (msg.equals("-q")) {
break;
}
msg = "null" + ":" + msg + ":" + Configs.MSG_PUBLIC;
out.write(msg.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static void privateTalk() {
try {
System.out.println("当前处于私聊模式.......");
while (true) {
String msg = sc.nextLine();
if ("-q".equals(msg)) {
break;
}
msg = msg + ":" + Configs.MSG_PRIVATE;
out.write(msg.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端读取消息的线程:
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import Clinet.untils.TimeUtil;
import Configs.Configs;
public class ClientThread extends Thread {
private InputStream in;
boolean flag=true;
public ClientThread(InputStream in) {br/>this.in=in;
}
@Override
public void run() {
try {
while(flag) {
byte[] bys=new byte[1024];
int len=in.read(bys);
String client=new String(bys, 0, len);
String[] split=client.split(":");
String sender=split[0];
String msg=split[1];
int msgType=Integer.parseInt(split[2]);
long time=Long.parseLong(split[3]);
int num=1;
String data=TimeUtil.changeMils2Date(time, "yyyy-MM-dd HH:mm:ss");
if(msgType==Configs.MSG_PRIVATE) {
//私聊
System.out.println(data);
System.out.println(sender+"对你说:"+msg);
}else if(msgType==Configs.MSG_PUBLIC) {
//公聊
System.out.println(data);
System.out.println(sender+"对大家说:"+msg);
}else if(msgType==Configs.MSG_ONLINE) {
System.out.println(sender+msg+data);
}else if(msgType==Configs.MSG_ONLIST) {
System.out.println(msg);
}else if(msgType==Configs.MSG_EXIT) {
System.out.println(sender+msg);
}
}
} catch (SocketException e) {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
工具
消息类型模式:
public class Configs {
//私聊
//ctrl+shift+x :小转大
//ctrl+shift+y:大转小
public static final int MSG_PRIVATE = 100 ;
//公聊
public static final int MSG_PUBLIC = 200 ;
//上线提醒
public static final int MSG_ONLINE = 300 ;
//在线列表
public static final int MSG_ONLIST =400 ;
//退出
public static final int MSG_EXIT = 500 ;
//文件
public static final int MSG_FILE = 600 ;
}
客户端录入信息为整数工具:
import java.util.Scanner;
public class InputUtil {
public static int inputIntType(Scanner sc) {
int choose = 0;
while (true) {
try {
//录入用户输入的整数
choose = sc.nextInt();
break;
} catch (Exception e) {
sc = new Scanner(System.in);
System.out.println("输入的类型不正确,请重新输入:");
}
}
return choose;
}
}
将时间毫秒数转换为制定的日期格式工具类:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimeUtil {
//2016-10-27 19:20:12 yyyy-MM-dd HH:mm:ss
public static String changeDate2Week(String dateStr,String formatStr){
SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
Date date = null;
try {
date = sdf.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat sdf1 = new SimpleDateFormat("E");
return sdf1.format(date);
}
//把字符串的日期转为毫秒数
public static long changeDate2Mils(String dateStr,String formatStr){
SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
Date date = null;
try {
date = sdf.parse(dateStr);
} catch (ParseException e) {
e.printStackTrace();
}
return date.getTime();
}
//把毫秒数转为指定的格式的日期
public static String changeMils2Date(long mils,String formatStr){
SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
Date date = new Date(mils);
return sdf.format(date);
}
public static String changeDate2CustomerMsg(String dateStr){
long mils = changeDate2Mils(dateStr,"yyyy-MM-dd_HH:mm:ss");
long nowMils = System.currentTimeMillis();
long offsetMils = nowMils - mils;
String msg = "";
if(offsetMils<1000*60*2){
msg = "刚刚";
}else if(offsetMils<1000*60*60){
msg = (offsetMils/(1000*60))+"分钟前";
}else if(offsetMils<1000*60*60*24){
msg = (offsetMils/(1000*60*60))+"小时前";
}else if(offsetMils<1000*60*60*24*2){
msg = "昨天";
}else{
String nowYear = changeMils2Date(nowMils, "yyyy");
String year = changeMils2Date(mils, "yyyy");
if(nowYear.equals(year)){
msg = changeMils2Date(mils, "MM月dd日");
}else{
msg = changeMils2Date(mils, "yyyy年MM月dd日");
}
}
return msg;
}
}
服务端--------------------------------------------------------------------------------------------------------------------------------------------------------
服务端import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import UserCheck.ServerUserCheck;
public class ServerDemo {
public static void main(String[] args) throws IOException {
HashMap hm = new HashMap();
ServerSocket ss=new ServerSocket(1008);
System.out.println("服务器已开启,正在等待客户端的连接...");
int i=1;
while(true) {
Socket s=ss.accept();
System.out.println("第"+(i++)+"个客户端已连接...");
InputStream in=s.getInputStream();
OutputStream out=s.getOutputStream();;
ServerUserCheck su=new ServerUserCheck(s,hm);
su.start();
}
}
}
服务端保存用户名的线程:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Set;
import Configs.Configs;
import Server.ServerThread;
public class ServerUserCheck extends Thread {
private Socket s;
private HashMap
private String username;
public ServerUserCheck(Socket s, HashMap hm) {
this.hm = hm;
this.s = s;
}
@Override
public void run() {
try {
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
while (true) {
byte[] bys = new byte[1024];
int len = in.read(bys);
username = new String(bys, 0, len);
if (!hm.containsKey(username)) {
hm.put(username, s);
out.write("yes".getBytes());
break;
} else {
out.write("no".getBytes());
}
}
Set keySet = hm.keySet();
for (String key : keySet) {
if (key.equals(username)) {
break;
}
String online = username + ":" + "上线了..." + ":" + Configs.MSG_ONLINE + ":" + System.currentTimeMillis();
Socket s = hm.get(key);
OutputStream ou = s.getOutputStream();
ou.write(online.getBytes());
}
new ServerThread(hm, s, username).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端转发信息的线程:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Set;
import Configs.Configs;
public class ServerThread extends Thread {
private HashMap hm;
private Socket s;
private String username;
public ServerThread(HashMap hm, Socket s, String username) {
this.hm = hm;
this.s = s;
this.username = username;
}
@Override
public void run() {
try {
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
while (true) {
byte[] bys = new byte[1024];
int len = in.read(bys);
String client = new String(bys, 0, len);
String[] msgs = client.split(":");
//接收者
String receiver = msgs[0] ;
//消息内容
String msgContent = msgs[1] ;
//消息类型
int msgType = Integer.parseInt(msgs[2]) ;
//拆分消息之后,重新组装消息,约定服务器转发格式
//发送者:消息内容:消息类型:时间
long time = System.currentTimeMillis() ;
if (msgType == Configs.MSG_PRIVATE) {
Socket s = hm.get(receiver);
String zfMsg = username + ":" +msgContent + ":" + msgType + ":" + time;
s.getOutputStream().write(zfMsg.getBytes());
} else if (msgType == Configs.MSG_PUBLIC) {
Set keySet = hm.keySet();
for (String key : keySet) {
if (username.equals(key)) {
continue;
}
Socket s = hm.get(key);
String zfMsg = username + ":" + msgContent + ":" + msgType + ":" + time;
s.getOutputStream().write(zfMsg.getBytes());
}
} else if (msgType == Configs.MSG_ONLIST) {
Set keySet = hm.keySet();
StringBuffer sb = new StringBuffer();
int i = 1;
for (String key : keySet) {
if (key.equals(username)) {
continue;
}
sb.append(i++).append(",").append(key).append("\n");
}
String zfMsg = username + ":" + sb.toString() + ":" + Configs.MSG_ONLIST + ":" + time;
Socket s = hm.get(username);
s.getOutputStream().write(zfMsg.getBytes());
}else if(msgType==Configs.MSG_EXIT) {
Set keySet = hm.keySet();
for(String key:keySet) {
if(key.equals(username)) {
continue;
}
Socket ou = hm.get(key);
String zfMsg=username+":"+"下线了"+":"+Configs.MSG_EXIT+":"+time;
ou.getOutputStream().write(zfMsg.getBytes());
}
break;
}
}
hm.get(username).close();
hm.remove(username);
} catch (NumberFormatException e) {
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}