package com.softeem.chat;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 聊天室的服务端
* @author Mr.zhou
*
*/
public class ChatServer {
//客户对象的集合,用于存放所有客户端
private List<User> clients = new ArrayList<User>();
/**
* 初始化服务端
*/
private void init(){
//套接字
Socket socket = null;
//服务于服务端的套接字 Alt + /
ServerSocket ss = null;
try {
//指定端口号
ss = new ServerSocket(8088);
System.out.println("等待连接");
} catch (IOException e) {
//输出异常
System.out.println("端口被占用了");
e.printStackTrace();
}
try {
User user = null;
//循环监听是否有客户端接入
while(true){
socket = ss.accept();
System.out.println("已有用户接入");
user = new User(socket);
//将接入的用户装入到集合中
clients.add(user);
//启动线程
new Thread(user).start();
}
} catch (IOException e) {
e.printStackTrace();
}
//接收客户端发出的消息
}
//服务端主程序入口
public static void main(String[] args) {
new ChatServer().init();
}
//使用内部类的形式来创建用户对象,由于有多个用户需要同时聊天,所以使用线程创建用户对象
private class User implements Runnable{
private Socket socket = null;
private InputStream is = null;
private DataInputStream dis = null;
private OutputStream os = null;
private DataOutputStream dos = null;
//声明一个布尔类型的参数用来标记是否继续接收
private boolean flag = true;
public User(Socket socket){
this.socket = socket;
try {
is = socket.getInputStream();
dis = new DataInputStream(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//将消息转发给其他客户端
private void forwordToAllClient(String message){
for (User user : clients) {
if(user != this){
//发送
try {
dos = new DataOutputStream(user.socket.getOutputStream());
dos.writeUTF(message);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//将该线程所要执行的方法写入run方法中
@Override
public void run() {
String message;
//循环接收客户端的消息
while(flag){
//使用数据输入流读取
try {
message = dis.readUTF();
System.out.println("客户端说:"+message);
forwordToAllClient(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.softeem.chat;
import java.awt.BorderLayout;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
/**
* 聊天室的客户端
* @author Mr.zhou
*
*/
public class Client extends JFrame {
//文本浏览组件
private TextArea textAreaContent = new TextArea();
//文本输入框组件
private TextField textFieldContent = new TextField();
//套接字
private Socket socket = null;
//文件输入流
private InputStream is = null;
//数据输入流
private DataInputStream dis = null;
//文件输出流
private OutputStream os = null;
//数据输出流
private DataOutputStream dos = null;
//初始化客户端
private void init(){
//设置窗体大小
this.setSize(400, 300);
//设置窗体标题
this.setTitle("Softeem聊天室");
//设置窗体居中显示
this.setLocationRelativeTo(null);
//添加组件
this.add(textAreaContent);//添加文本浏览组件
this.add(textFieldContent,BorderLayout.SOUTH);//将文本输入框组件添加到南方向(下)
textAreaContent.setFocusable(false);//设置文本浏览组件只读
//将两组件捆绑到一起
pack();
//申请连接
conenct();
//对文本输入框添加一个回车按键的监听
textFieldContent.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//调用点击回车按键发生的事情的方法
onClickEnter();
}
});
//显示窗体
this.setVisible(true);
//启动线程
new Thread(new ReciveMessage()).start();
}
//客户端的启动程序
public static void main(String[] args) {
new Client().init();
}
//当点击键盘回车时发生的事件
private void onClickEnter(){
//读取文本输入框内的内容
String message = textFieldContent.getText().trim();
//非空判断
if(!"".equals(message) && message != null){
//根据指定的格式获取当前系统时间
String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(new Date());
//将输入框的内容发送到浏览框
textAreaContent.append(time + "\n"+message+"\n");
//将输入框的内容清空
textFieldContent.setText("");
//将文本信息发送给服务端
sendToServer(message);
// System.out.println(message);
}
}
//给服务端发送消息
public void sendToServer(String message){
try {
//将消息写出
dos.writeUTF(message);
//刷新
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
//建立连接的方法
private void conenct(){
try {
//发出连接申请
socket = new Socket("localhost", 8088);
//初始化文件输出流
os = socket.getOutputStream();
//将文件输出流包装成数据输出流
dos = new DataOutputStream(os);
//初始化文件输入流
is = socket.getInputStream();
//将文件输入流包装成数据输入流
dis = new DataInputStream(is);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//使用线程类接收服务端发送过来的消息
public class ReciveMessage implements Runnable{
@Override
public void run() {
boolean flag = true;
while(flag){
try {
//读取服务端发出的消息
String message = dis.readUTF();
System.out.println(message);
//将消息写入到文本浏览区域
textAreaContent.setText(message + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}