JavaSE学完之后,用java实现的聊天室融合了不少java知识.java
好比GUI简单的图形界面,集合,IO,多线程,socket,监听等.服务器
那么这个聊天系统是如何实现的呢?网络
首先咱们要有界面.如图所示.多线程
这仅仅是一个简单的Frame窗口界面.socket
首先package : 包入境,至关于这个类文件的绝对路径,与别人重复概率减少ide
import : 导入包/类的意思.当要想调用某个包中的类的方法,就要用到import 优化
extends : ChatClient01继承Frame,至关于,继承了父类Frame里面的全部方法this
接下来如图中代码所示,声明接下来要用到的变量,变量声明三步:指定数据类型,指定变量名,赋值spa
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(); } } }}