JavaSE学完以后,用java实现的聊天室融合了很多java知识.
比如GUI简单的图形界面,集合,IO,多线程,socket,监听等.
那么这个聊天系统是如何实现的呢?
首先我们要有界面.如图所示.
这仅仅是一个简单的Frame窗口界面.
首先package : 包入境,相当于这个类文件的绝对路径,与别人重复几率减小
import : 导入包/类的意思.当要想调用某个包中的类的方法,就要用到import
extends : ChatClient01继承Frame,相当于,继承了父类Frame里面的所有方法
接下来如图中代码所示,声明接下来要用到的变量,变量声明三步:指定数据类型,指定变量名,赋值
main : 程序的入口
实例化ChatClient01然后调用LaunchFrame()里面的方法,并且把它实现.
this : 就是指当前对象.
pack() : 调用pack()方法,这个方法就是依据你放置的组件设定窗口的大小 使之正好能容纳你放置的所有组件
setVisible() : 设置可视化窗口可见.
窗口实现了,接下来就该实现对窗口的一些响应.
这个过程就是对这个Frame窗口进行了监听,感应,让他实现某些功能.
这里就已经连接到了服务器.使用到了socket,那么socket就是网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket
说简单就就像插座.
Socket通讯的过程:1 创建socket
2 打开链接到socket的输入输出流
3 对socket进行读写操作
4 关闭socket
这个就可以实现发送功能了.
这里就实现了多个线程同时发送接收,实现对话.
那么这一步步是怎么实现的,我简单说一下我的理解.
界面--->控件监听/感应--->添加服务器--->链接服务器--->把数据发送到服务器,并且获得客户端数据并输出--->接受多线程客户端请求--->优化--->关闭数据接受线程
总体来说,就差不多完整了.其中可能在涉及到服务端以及多线程客户请求的时候可能有些麻烦,但细心一点,认真一点,会ok
刚开始的程序只能实现Server和一个客户的对话,为了实现在服务器方给多个客户提供服务的功能,需要对开始单线程的程序进行改造,利用多线程实现多客户机制.
聊天室服务端:
public class ChatServer {
boolean started = false;
ServerSocket ssoc = null;//对象变量
ArrayList<Client> clients = new ArrayList<Client>();//存放对象的集合
public static void main(String[] args) {
new ChatServer().serverStart();
}
private void serverStart(){
try {
ssoc = new ServerSocket(8888);//创建一个ServerSocket在端口8888监听客户请求
started = true;
} catch (BindException e) { //出错,出错信息
System.out.println("服务器端口已经被占用");
System.out.println("请关闭服务器重新启动");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
try {
while (started) {//循环等待客户端连接
Socket soc;
try {
soc = ssoc.accept();//使用accept()阻塞等待客户请求,有客户,请求到来则产生一个Socket对象,并继续执行
boolean bConnected = false;
Client c = new Client(soc);
new Thread(c).start();//开始一个线程
clients.add(c);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO: handle exception
}
}
private class Client implements Runnable {
private DataOutputStream dos = null;
DataInputStream dis = null;
Socket soc = null;
boolean started = false;
boolean bConnected = false;
public Client(Socket soc) {
try {
this.soc = soc;
dis = new DataInputStream(soc.getInputStream());//得到输入流
dos = new DataOutputStream(soc.getOutputStream());//得到输出流
bConnected = true;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() { //针对每个socket进行
try {
while (bConnected) {
String str = dis.readUTF();
System.out.println(str);
for (int i = 0; i < clients.size(); i++) {
Client c = clients.get(i);
c.send(str);
}
}
} catch (EOFException e) {
System.out.println("客户端退出");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (dis != null) {
dis.close();
}
if (soc != null) {//socket不为空
soc.close();//关闭socket
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
public void send(String str) {//发送
try {
dos.writeUTF(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}