介于JAVAswing和Socket写的聊天室
在厦门的第一阶段给我们复习了JAVASE基础,第一阶段的小玩具叫我们自选题材,我自己选了聊天室这个内容,这个小玩具无论是线程,还是网络编程,都会涉及到,比较有综合性,所以我选了这个;
这是我的包体结构:

类包,JDBC工具包,界面包
首先讲一下思路,聊天室是一个端对端的数据传输平台,然而Socket一般来说只是个点对点的数据传输,这样的话,为了解决这个问题,我将所有的接入本服务器的客户端都给了一个List接收,离开时通过语句判断将他移除,有客户端发消息时便将信息广播给在List中的客户端,代码如下:
public class Server {
int port;
List<Socket> clients;//接入本服务器的客户端
ServerSocket server;
public static void main(String[] args) {
new Server();
}
public Server() {
try {
port = 8080;
clients = new ArrayList<Socket>();
server = new ServerSocket(port);
System.out.println("...........");
while (true) {
//时刻监测是否有客户端接入,接入则加入
Socket socket = server.accept();
System.out.println(socket);
clients.add(socket);
Mythread mythread = new Mythread(socket);
mythread.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
class Mythread extends Thread {
Socket ssocket;
private BufferedReader br;
private PrintWriter pw;
public String msg;
public Mythread(Socket s) {
ssocket = s;
}
public void run() {
//该方法用于监测是否有客户端传来消息
try {
br = new BufferedReader(new InputStreamReader(
ssocket.getInputStream()));
msg = "欢迎进入聊天室!当前聊天室有【"
+ clients.size() + "】人";
sendMsg();
while ((msg = br.readLine()) != null) {
msg = "【" + ssocket.getInetAddress() + "】" + msg;
sendMsg();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void sendMsg() {
try {// 监测发内容是否是离开格式
System.out.println(msg);
String[] aaStrings = msg.split("-");
for (int i = 0; i < clients.size(); i++) {
if (clients.get(i).toString().split(",")[0]
.equals(aaStrings[1].split(",")[0])) {
System.out.println("有人离开了聊天室!!");
clients.remove(i);
break;
}
}
} catch (Exception ex) {
for (int i = 0; i < clients.size(); i++) {//遍历发送信息
try {
pw = new PrintWriter(clients.get(i).getOutputStream(),
true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
pw.println(msg);
pw.flush();
}
}
}
}
}
将这个问题解决了,客户端便也不是个难题了,我把发送消息封装在了Client中:
public class ClientDao {
Socket socket;
String message;
public ClientDao(String message, Socket socket) {
this.message = message;
this.socket = socket;
}
//发送消息
public void send(String message, Socket socket) {
OutputStream os;
try {
//获取socket的输出流
os = socket.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//将消息发送出去
bw.write(message);
//换行
bw.newLine();
bw.flush(); // 清空缓存
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
由于我需要将用户信息传输给下一个页面,于是我将窗口的构造方法重写了具体实现代码如下:
public class TalkClient extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField sendText;
private JTextArea jta;
public static boolean connect = false; // 客户端是否连接
ClientDao cDao;
public int port = 8080;
Socket socket = null;
String msg2;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TalkClient frame = new TalkClient();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TalkClient() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
msg2= "asdasd" +"-"+socket+"-"+"close";
cDao=new ClientDao(msg2, socket);
cDao.send(msg2, socket);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 505, 477);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
sendText = new JTextField();
sendText.setBounds(120, 257, 343, 43);
contentPane.add(sendText);
sendText.setColumns(10);
JLabel label = new JLabel("\u6D88\u606F\u8BB0\u5F55\uFF1A");
label.setBounds(34, 15, 76, 15);
contentPane.add(label);
jta= new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setBounds(120, 10, 343, 220);
jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
getContentPane().add(jsp);
JLabel label_1 = new JLabel("\u5F85\u53D1\u9001\u6D88\u606F\uFF1A");
label_1.setBounds(34, 271, 76, 15);
contentPane.add(label_1);
JLabel namelb = new JLabel("");
namelb.setBounds(90, 354, 54, 15);
contentPane.add(namelb);
JButton sendBtn = new JButton("\u53D1\u9001");
sendBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//發送消息
//msg2=sendText.getText().toString().trim();
//jta.append("\n客户端说:" + sendText.getText().toString());
msg2 = sendText.getText().toString() ;
//System.out.println(socket);
cDao=new ClientDao(msg2, socket);
cDao.send(msg2, socket);
}
});
sendBtn.setBounds(301, 350, 93, 23);
contentPane.add(sendBtn);
connectServer();
new Thread(new Runnable() {
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg1;
while ((msg1 = br.readLine()) != null) {
jta.append("\n"+":"+msg1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public TalkClient(final User user) {
// TODO Auto-generated constructor stub
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 505, 477);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
sendText = new JTextField();
sendText.setBounds(120, 257, 343, 43);
contentPane.add(sendText);
sendText.setColumns(10);
JLabel label = new JLabel("\u6D88\u606F\u8BB0\u5F55\uFF1A");
label.setBounds(34, 15, 76, 15);
contentPane.add(label);
jta= new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setBounds(120, 10, 343, 220);
jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
getContentPane().add(jsp);
JLabel label_1 = new JLabel("\u5F85\u53D1\u9001\u6D88\u606F\uFF1A");
label_1.setBounds(34, 271, 76, 15);
contentPane.add(label_1);
JLabel namelb = new JLabel("");
namelb.setBounds(90, 354, 54, 15);
contentPane.add(namelb);
JButton sendBtn = new JButton("\u53D1\u9001");
sendBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//發送消息
//jta.append(user.getUserName() + sendText.getText().toString());
msg2 =user.getUserName()+"说:"+ sendText.getText().toString() ;
//System.out.println(socket);
cDao=new ClientDao(msg2, socket);
cDao.send(msg2, socket);
}
});
sendBtn.setBounds(301, 350, 93, 23);
contentPane.add(sendBtn);
connectServer();
namelb.setText(user.getUserName());
new Thread(new Runnable() {
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg1;
while ((msg1 = br.readLine()) != null) {
System.out.println("xiaoxi"+msg1);
jta.append("\n"+msg1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
msg2=user.getUserName()+"-"+socket+"-"+"close";
cDao=new ClientDao(msg2, socket);
cDao.send(msg2, socket);
}
});
}
public boolean connectServer() {
try {
// 获取输入的IP地址,并且进行连接
socket = new Socket("192.168.6.196", 8080);
jta.append("\n连接服务器成功!");
connect = true;
return true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
jta.append("\n连接失败");
}
return false;
}
}
这里我就不将那些JDBC,贴上来了,基本上这样就好了
介于JAVAswing和Socket写的聊天室的更多相关文章
- 使用socket.io搭建聊天室
最近在学习nodejs,需要找一些项目练练手.找来找去发现了一个聊天室的教程,足够简单,也能从中学到一些东西.下面记录我练习过程中待一些笔记. nodeJS模块 共用到了2个模块,express和so ...
- node.js + socket.io实现聊天室一
前段时间,公司打算在社区做一个聊天室.决定让我来做.本小白第一次做聊天类功能,当时还想着通过ajax请求来实现.经过经理提示,说试试当前流行的node.js 和socket.io来做.于是就上网学习研 ...
- 【C++】基于socket的多线程聊天室(控制台版)
以前学习socket网络编程和多线程编程的时候写的一个练手程序 聊天室基本功能: 1.用户管理:登录,注册,登出,修改用户名,修改密码 2.聊天室功能:群聊,私聊,获取在线用户列表,获取所有用户列表 ...
- 使用 Socket.IO 开发聊天室
前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...
- 使用原生node写一个聊天室
在学习node的时候都会练习做一个聊天室的项目,主要使用socket.io模块和http模块.这里我们使用更加原始的方式去写一个在命令行聊天的聊天室. http模块,socket.io都是高度封装之后 ...
- C#基于Socket的简单聊天室实践
序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...
- 【总结】学习Socket编写的聊天室小程序
1.前言 在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门很高深的学问,本文只是Socket一些最基础的东西,大神请自觉绕路. 传输协议 TCP:Tra ...
- Socket.io在线聊天室
从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏 ...
- Socket.io官方聊天室DEMO的学习笔记
照着Socket.io官方的聊天室代码敲了一遍,遇到了一个奇怪的问题: 每次点击SEND按钮的时候,都会重新刷新页面. 在点击页面的一瞬间,看到了正在加载jquery的提示, 然后以为是jquery用 ...
随机推荐
- pdf转换成jpg不清晰怎么办
用Photoshop打开pdf文件,然后用“文件”-“另存为”“JPG”.
- git中配置的.gitignore不生效的解决办法
通常我们希望放进仓库的代码保持纯净,即不要包含项目开发工具生成的文件,或者项目编译后的临时文件.但是,当我们使用git status查看工作区状态的时候,总会提示一些文件未被track.于是,我们想让 ...
- 局域网-断网&劫持(kali)
1.查看局域网中的主机 fping –asg 192.168.1.0/24 2.断网 arpspoof -i wlan0 -t 192.168.100 192.168.1.1 (arpspoof - ...
- JVM中的逃逸分析
逃逸分析(Escape Analysis)是目前Java虚拟机中比较前沿的优化技术. 逃逸分析的基本行为就是分析对象动态作用域:当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递 ...
- linux安装Elasticsearch详细步骤
坑都已经踩好了 照着步骤一次成功 不多废话 走起 # ## 安装java运行环境 elasticsearch是用Java实现的 跑elasticsearch必须要有jre支持 所以必须先安装jre ...
- 三、SpringBoot整合Thymeleaf视图
目录 3.1 Thymeleaf视图介绍 3.2 创建SpringBoot项目 3.2 配置Thymeleaf 3.3 编写Demo 3.4 小结 3.1 Thymeleaf视图介绍 先看下官网的介绍 ...
- golang爬虫
- Array : 数组的常用方法
数组常用方法 对象通用方法 1.toLocalString() 数组中的每个元素都会调用toLocalString(),然后以逗号隔开, 拼接为字符串: 2.toString() 数组中的每个元素都 ...
- pytest_函数传参和firture传参数request
前言为了提高代码的复用性,我们在写用例的时候,会用到函数,然后不同的用例去调用这个函数. 比如登录操作,大部分的用例都会先登录,那就需要把登录单独抽出来写个函数,其它用例全部的调用这个登陆函数就行. ...
- Gradle 翻译 build dependencies 依赖 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...