在厦门的第一阶段给我们复习了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写的聊天室的更多相关文章

  1. 使用socket.io搭建聊天室

    最近在学习nodejs,需要找一些项目练练手.找来找去发现了一个聊天室的教程,足够简单,也能从中学到一些东西.下面记录我练习过程中待一些笔记. nodeJS模块 共用到了2个模块,express和so ...

  2. node.js + socket.io实现聊天室一

    前段时间,公司打算在社区做一个聊天室.决定让我来做.本小白第一次做聊天类功能,当时还想着通过ajax请求来实现.经过经理提示,说试试当前流行的node.js 和socket.io来做.于是就上网学习研 ...

  3. 【C++】基于socket的多线程聊天室(控制台版)

    以前学习socket网络编程和多线程编程的时候写的一个练手程序 聊天室基本功能: 1.用户管理:登录,注册,登出,修改用户名,修改密码 2.聊天室功能:群聊,私聊,获取在线用户列表,获取所有用户列表 ...

  4. 使用 Socket.IO 开发聊天室

    前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...

  5. 使用原生node写一个聊天室

    在学习node的时候都会练习做一个聊天室的项目,主要使用socket.io模块和http模块.这里我们使用更加原始的方式去写一个在命令行聊天的聊天室. http模块,socket.io都是高度封装之后 ...

  6. C#基于Socket的简单聊天室实践

    序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...

  7. 【总结】学习Socket编写的聊天室小程序

    1.前言 在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门很高深的学问,本文只是Socket一些最基础的东西,大神请自觉绕路. 传输协议 TCP:Tra ...

  8. Socket.io在线聊天室

    从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发.Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎.chrome浏 ...

  9. Socket.io官方聊天室DEMO的学习笔记

    照着Socket.io官方的聊天室代码敲了一遍,遇到了一个奇怪的问题: 每次点击SEND按钮的时候,都会重新刷新页面. 在点击页面的一瞬间,看到了正在加载jquery的提示, 然后以为是jquery用 ...

随机推荐

  1. CSS选择子简明参考

    Type Selector Example h1 { } Description Selects an HTML tag/element. Universal selector Example * { ...

  2. go 代码玩耍

    //小游戏 num := rand.Intn() var input int fmt.Println("请输入数字") fmt.Scanf("%d", & ...

  3. [UE4] Adding a custom shading model

    转自:https://blog.felixkate.net/2016/05/22/adding-a-custom-shading-model-1/ This was written in Februa ...

  4. dva+umi+antd项目从搭建到使用

    先创建一个新项目,具体步骤请参考https://www.cnblogs.com/darkbluelove/p/11338309.html 一.添加document.ejs文件(参考文档:https:/ ...

  5. SpringBoot加载自定义yml文件

    自定义配置文件(跟SpringBoot的application.yml同一目录下): nlu-parse-rule: title: "NLU响应结果解析规则" desc: &quo ...

  6. 长乐国庆集训Day4

    T1 一道数论神题 题目 [题目描述] LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删 ...

  7. 在js中使用for和forEach遍历数组

    数组的遍历 for var arr = [1, 2, 3, 4]; for (var i = 0; i < arr.length; i++){ arr[i]; } forEach var arr ...

  8. js中基本包装类型详情

    基本包装类型 基本包装类型有Boolean,Number和string类型,每当读取一个基本类型值时,后台就会创建一个对应的基本包装类型对象. 从逻辑上,基本类型值不是对象,没有方法,但从技术上来看, ...

  9. 刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?(没有BOM,所以被误判为UTF8。“联通”两个汉字的GB内码,其第一第二个字节的起始部分分别是“110”和“10”,,第三第四个字节也分别是“110”和“10”)

    1. 当用一个软件(比如Windows记事本或Notepad++)打开一个文本文件时,它要做的第一件事是确定这个文本文件究竟是使用哪种编码方式保存的,以便于该软件对其正确解码,否则将显示为乱码. 一般 ...

  10. 【题解】Luogu P5304 [GXOI/GZOI2019]旅行者

    原题传送门 题意:给你k个点,让你求两两最短路之间的最小值 我们考虑二进制拆分,使得每两个点都有机会分在不同的组\((A:0,B:1)\)中,从源点\(S\)向\(A/B\)中的点连边权为0的边,从\ ...