Client段
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
public class ChatClient extends Thread implements ActionListener {
JFrame jframe = new JFrame("聊天室,客户端");
JTextArea jta = new JTextArea(10, 30);// 保存聊天信息
JList list = new JList();// 保存聊天用户列表
JTextField jtf1 = new JTextField("匿名", 10);
JLabel lab1 = new JLabel("昵称");
JTextField jtf2 = new JTextField(10);
JLabel lab2 = new JLabel("服务器");
JButton connBtn = new JButton("连接");
JLabel lab3 = new JLabel("消息");
JTextField jtf3 = new JTextField(20);// 聊天输入框
JButton sendBtn = new JButton("发送");
JCheckBox box = new JCheckBox("启动私聊");
PrintWriter pw;
BufferedReader br;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
DefaultListModel model = new DefaultListModel();
Hashtable<String, String> table = new Hashtable<String, String>();// 保存编号和呢称
public void paint() {
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
connBtn.addActionListener(this);
Container container = jframe.getContentPane();
JPanel northPanel = new JPanel();
northPanel.setBackground(Color.YELLOW);
northPanel.add(lab1);
northPanel.add(jtf1);
northPanel.add(lab2);
northPanel.add(jtf2);
northPanel.add(connBtn);
connBtn.setBackground(Color.YELLOW);
sendBtn.setBackground(Color.GREEN);
sendBtn.addActionListener(this);
box.setBackground(Color.GREEN);
JPanel southPanel = new JPanel();
southPanel.setBackground(Color.GREEN);
southPanel.add(box);
southPanel.add(lab3);
southPanel.add(jtf3);
southPanel.add(sendBtn);
JPanel westPanel = new JPanel(new BorderLayout());
JLabel userLab = new JLabel("成员列表");
westPanel.setBackground(Color.RED);
JScrollPane userPanel = new JScrollPane(list);
list.setBackground(Color.PINK);
westPanel.add(userLab, BorderLayout.NORTH);
westPanel.add(userPanel, BorderLayout.CENTER);
westPanel.setPreferredSize(new Dimension(100, 480));
JScrollPane centerPanel = new JScrollPane(jta);
jta.setBackground(Color.LIGHT_GRAY);
container.add(northPanel, BorderLayout.NORTH);
container.add(southPanel, BorderLayout.SOUTH);
container.add(westPanel, BorderLayout.WEST);
container.add(centerPanel, BorderLayout.CENTER);
list.setModel(model);
jframe.setSize(480, 480);
jframe.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
String name = e.getActionCommand();
if (name.equals("连接")) {
conn();
} else if (name.equals("发送")) {
printMessage();
}
}
public void conn() {
try {
Socket s = new Socket(jtf2.getText(), 1234);
connBtn.setEnabled(false);
pw = new PrintWriter(s.getOutputStream(), true);
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
this.start();// 启动接收聊天信息线程
} catch (UnknownHostException e) {
jta.append("连接服务器失败,请正确输入服务器地址\n");
} catch (IOException e) {
jta.append("连接服务器失败\n");
}
}
public void printMessage() {
if (pw != null) {
if (!box.isSelected()) {// 处理正常聊天信息
Date d = Calendar.getInstance().getTime();
String fmt = sdf.format(d);
pw
.println(fmt + " " + jtf1.getText() + "说 : "
+ jtf3.getText());
jtf3.setText("");
pw.flush();
} else {// 处理私聊信息
Date d = Calendar.getInstance().getTime();
User p = (User) list.getSelectedValue();// 得到私聊用户对象
if (p == null)
return;
String fmt = sdf.format(d);// ~代表是私聊的开始 p.getId()代表对谁进行私聊
pw.println("~" + p.getId() + "~" + "【私聊】" + fmt + " "
+ jtf1.getText() + "对你说 : " + jtf3.getText());
jta.append("【私聊】" + fmt + " " + "你对【" + p.getName() + "】说 : "
+ jtf3.getText() + "\n");
jtf3.setText("");
pw.flush();
}
}
}
public void run() {
pw.println("@" + jtf1.getText());
while (true) {
try {
String msg = br.readLine();
if (msg.startsWith("@")) {// 得到的是用户登陆信息
String userList[] = msg.split("@");
table.put(userList[2], userList[1]);// 保存得到的用户编号和呢称
User p = new User();// 以此编号和呢称创建一个用户
p.setId(userList[2]);
p.setName(userList[1]);
model.addElement(p);// 将用户显示在列表中
list.setModel(model);
} else if (msg.startsWith("#")) {// 得到的是用户退出信息
String userList[] = msg.split("#");
String id = userList[1];
User p = new User();
p.setId(id);// 通过编号创建一个User对象
model.removeElement(p);// 删除列表中与此编号相同的用户
list.setModel(model);// 从新显示列表
} else
jta.append(msg + "\n");// 正常聊天信息
} catch (IOException e) {
jta.append("与服务器断开连接\n");
break;
}
}
}
public static void main(String[] args) {
new ChatClient().paint();
}
}
Sever段
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
public class ChatServer implements ActionListener {
private JFrame jframe = new JFrame("聊天室,服务器");
JTextArea jta = new JTextArea(10, 20);
JTextField jtf = new JTextField(20);
OutputStream os = null;
PrintWriter pw = null;
Vector<Socket> v = new Vector<Socket>();//保存所有客户端
Hashtable<String, String> table = new Hashtable<String, String>();//保存用户编号和呢称
Hashtable<Socket, String> socketTable = new Hashtable<Socket, String>();//保存客户端和用户编号
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
public void paint() {
Container container = jframe.getContentPane();
JPanel northPanel = new JPanel();
JLabel lab1 = new JLabel("系统消息");
JButton btn = new JButton("发送");
btn.addActionListener(this);
northPanel.add(lab1);
northPanel.add(jtf);
northPanel.add(btn);
JScrollPane context = new JScrollPane(jta);
container.add(northPanel, BorderLayout.NORTH);
container.add(context);
jframe.setSize(480, 400);
jframe.setVisible(true);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createServer();
}
public void createServer() {
try {
ServerSocket ss = new ServerSocket(1234);//创建服务器
jta.append("服务器已经启动\n");
while (true) {
Socket s = ss.accept();//等待客户端连接
os = s.getOutputStream();
pw = new PrintWriter(os, true);
new Service(s);//启动与客户端交互的线程
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
writeMessage();//发送系统消息
}
public void writeMessage() {//发送系统消息
Date d = Calendar.getInstance().getTime();
String fmt = sdf.format(d);
int size = v.size();// v保存的是所有的客户端
for (int i = 0; i < size; i++) {
Socket sk = v.get(i);
try {
PrintWriter pw = new PrintWriter(sk.getOutputStream(), true);
pw.println(fmt + " 系统消息 : " + jtf.getText());
} catch (IOException e) {
continue;
}
}
jtf.setText("");
}
private class Service extends Thread {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
Socket s;
public Service(Socket s) {
try {
this.s = s;
is = s.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
} catch (Exception e) {
e.printStackTrace();
}
this.start();//启动交互线程
}
public void run() {
while (true) {
try {
String msg = br.readLine();//读取客户端发送的消息
sendAll(s, msg);//处理发送的消息
} catch (IOException e) {
v.remove(s);
String id = socketTable.remove(s);
String name = table.remove(id);
jta.append("【" + name + "】" + "离开聊天室...");
jta.append("服务器现在人数为: " + v.size() + "人\n");
sendAll(s, "#" + id);//处理用户退出消息
break;
}
}
}
synchronized public void sendAll(Socket s, String msg) {
if (msg.startsWith("@")) {//处理用户登陆消息
String id = System.currentTimeMillis() + "";
msg = msg + "@" + id;
String str[] = msg.split("@");
table.put(id, str[1]);//保存编号和对应的呢称
socketTable.put(s, id);//保存客户端和对应的编号
v.add(s);//保存客户端
jta.append("【" + str[1] + "】" + "进入聊天室...");
jta.append("服务器现在人数为: " + v.size() + "人\n");
try {
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
Set<String> set = table.keySet();
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String clientID = it.next();
pw.println("@" + table.get(clientID) + "@" + clientID);//将登陆消息发给自己
}
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < v.size() - 1; i++) {//将登陆消息发给以前登陆的客户端
Socket sk = v.get(i);
try {
PrintWriter pw = new PrintWriter(sk.getOutputStream(),
true);
pw.println(msg);
} catch (IOException e) {
continue;
}
}
} else if (msg.startsWith("~")) {//处理私聊信息
String privateMsg[] = new String[2];
privateMsg[0] = msg.substring(1, msg.indexOf("~", 1));
privateMsg[1] = msg.substring(msg.indexOf("~", 1)+1, msg.length());
String toID = privateMsg[0];//保存的是用户的编号
Set<Socket> coll = socketTable.keySet();
Iterator<Socket> it = coll.iterator();
while (it.hasNext()) {
Socket id = it.next();
if (socketTable.get(id).equals(toID)) {//通过客户端找用户的编号
try {
PrintWriter pw = new PrintWriter(id
.getOutputStream(), true);
pw.println(privateMsg[1]);//如果编号相同则发给此客户端
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
for (int i = 0; i < v.size(); i++) {//处理正常的聊天消息
Socket sk = v.get(i);
try {
PrintWriter pw = new PrintWriter(sk.getOutputStream(),
true);
pw.println(msg);
} catch (IOException e) {
continue;
}
}
}
}
}
public static void main(String[] args) {
new ChatServer().paint();
}
}
用来创建用户名称和id
public class User {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int hashCode() {
return id.hashCode();
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof User))
return false;
User user = (User) obj;
return this.id.equals(user.id);
}
public String toString() {
return this.name;
}
}
相关推荐
- **运行效果图**:展示的是聊天室运行时的用户界面和交互情况,可以帮助我们理解程序的功能和用户体验。 5. **项目完善**: - **安全性**:考虑添加身份验证和加密机制,防止未授权访问和信息泄露。 - **性能...
在这个"ExtJS实现聊天功能"的项目中,我们将探讨如何利用ExtJS框架构建一个类似于QQ的聊天应用程序。 首先,我们要理解聊天功能的核心要素。一个基本的聊天应用通常包含以下部分: 1. **用户界面**:ExtJS提供了...
在Android开发中,实现类似iPhone短信应用中的气泡聊天效果是一项常见的需求,它能为用户带来直观、友好的交互体验。本示例将探讨如何在Android应用中创建这样的功能。 首先,我们需要理解气泡聊天效果的基本概念。...
本资源名为“气泡聊天效果图”,显然是一个用于实现这种效果的代码或模板库,特别适合那些正在使用Qt框架进行界面开发的开发者。Qt是一个跨平台的C++图形用户界面应用程序开发框架,广泛应用于桌面、移动和嵌入式...
在仿QQ源代码中,聊天功能是核心部分。这涉及到客户端与服务器之间的实时通信,通常采用TCP/IP协议进行数据传输。开发者需要创建客户端和服务器两端的逻辑,处理消息发送、接收、显示以及历史记录存储。C#中的System...
1. 布局管理:通过`display`属性实现流式布局、网格布局或定位布局,使聊天窗口各部分有序排列。 2. 颜色与背景:使用`color`、`background-color`等属性定义元素颜色,以及使用渐变、图片等实现背景效果。 3. 字体...
"JS的100多个犀利效果(有效果图,有代码)"这个资源集合显然是一份宝贵的开发者工具包,包含了各种各样的JS特效,可以帮助开发者提升网页用户体验,同时也是一个学习和借鉴的好材料。 1. **动画效果**:JavaScript...
聊天室功能实现细节 实现一个功能完备的聊天室,需要对以下细节进行处理: - **表情图片输入**:通过JavaScript监听输入框事件,实现插入表情图片的功能。由于`contenteditable`不支持`<textarea>`的多行输入方式...
聊天界面是许多应用程序的核心组成部分,尤其是在社交、游戏或团队协作应用中。 首先,我们要理解`TableView`组件在Cocos2dx中的作用。`TableView`是一个可滚动的数据视图,它可以动态加载和显示大量的数据项,非常...
本篇文章将详细介绍如何利用`RecyclerView`来实现一个简单的聊天界面设计与功能。 首先,理解`RecyclerView`的基本结构。`RecyclerView`由`LayoutManager`、`Adapter`和`ViewHolder`三部分组成。`LayoutManager`...
6. **用户界面设计**:模仿QQ2013的界面,开发者需要对UI元素如按钮、文本框、图像等有深入理解,并能用代码实现类似的设计效果,可能涉及自定义控件和皮肤更换机制。 7. **事件驱动编程**:即时通讯软件需要响应...
在这个项目中,我们看到前端部分已经增加了聊天功能,这对于增强玩家之间的互动性至关重要。 首先,我们要了解HTML5的基础,它提供了Canvas API,允许开发者在网页上绘制图形。在Agar.io中,这个API被用来绘制游戏...
开发者需要将这些资源正确地引用到代码中,以实现完整的功能。 总的来说,QQ聊天界面iOS源代码素材提供了一个现成的框架,帮助开发者快速构建出与QQ类似的聊天应用。通过深入研究和理解这些源代码,开发者可以学习...
`Fly`可能是该项目的主要源代码文件夹,里面包含了实现文件传输和聊天功能的类和方法。在C#中,文件传输可能涉及到网络编程,特别是TCP/IP协议栈的使用,用于建立客户端和服务器之间的连接,实现数据的可靠传输。...
【jQuery仿微信聊天界面代码】是一个使用jQuery技术构建的项目,旨在实现类似微信聊天界面的交互效果。这个项目主要关注用户界面的呈现和交互体验,是前端开发中的一个实例,适用于学习和应用在Web应用程序中创建...
4. 在代码中使用这个点9图作为背景资源,应用到TextView或自定义的聊天气泡View上。 在给定的压缩包文件中,"点9图片"可能包含了制作好的点9聊天气泡资源。开发者可以将这些资源导入Android项目,然后在布局文件中...
本项目“漂亮的jQuery响应式聊天窗口代码”正是基于jQuery实现的一个功能丰富的聊天窗口,它具备现代Web应用所需的响应式设计,适应不同设备的屏幕尺寸。 首先,我们来探讨jQuery在聊天窗口中的应用。jQuery提供了...
【标题】中的“基于jquery实现的带返回顶部功能的在线客服网站侧边栏代码”表明这是一个使用jQuery库来创建的在线客服系统,该系统具备一个关键特性:返回顶部功能。在网页滚动时,用户可以方便地点击这个功能,快速...
"一个功能较完善的VB聊天软件"这个标题揭示了我们正在讨论的是一款用Visual Basic(VB)编程语言开发的聊天应用程序。这款软件不仅限于基本的文本聊天功能,还可能包含了多种增强用户体验的特性,如语音、视频聊天、...
这个"WPF msn聊天工具完整代码实例"对初学者和进阶者都有很大的学习价值。对于初学者,可以了解如何将WPF的基本元素和功能应用于实际项目;对于进阶者,可以研究其架构设计、网络通信实现以及用户体验优化等高级技巧...