javase的学习即将告一段落,作为最后的一个项目练习,仿聊天室的程序编写让我很是头疼了一阵子。说起来还是自己java基础不牢的缘故导致的,虽然整体框架都已经很清晰了但是实际编写过程中却依然磕磕绊绊,问题多多。经过一个周末大门不出的奋斗,如今总算是小有所得,做出了一个基本满足功能的程序,虽然依然有很多小bug,也不是最优的方案,但是毕竟是完全按照自己的思路写出来的,还是颇有些成就感。

现在我就对这个项目编写过程中自己遇到的一些问题做一个总结。

仿QQ聊天室程序,总的来说用到的知识点有:I/O,Socket套接字,AWT/swing,事件处理,JDBC,还有类集,多线程等,运用了cs架构(Client-Server)算是一个比较综合的项目。就我个人编写情况来看,主要的问题出现I/O,socket套接字和类集多线程部分。swing和事件处理在之前编写的那个计算器练习里得到了一定经验,这次在做聊天室的时候图形方面感觉问题不大了。I/O的话我对各种流的感觉比较混乱,尤其如今结合Socket在运用的时候很迷茫,我在这个项目的编写过程中运用了PrintStream打印流,采用了如下

PrintStream pt= new

PrintStream(client.getOutputStream());的方法进行客户端向服务器端地输出和服务器端向客户端的返回信息,但是这种方式在后期出现了很多问题,由于它只能以字符串的形式进行输出,携带的信息量很有限,在处理不同客户端发送过来的用户信息并将它们整合到指定类集中和向所有用户输出的时候很困难,虽然我最后通过它基本实现了功能,但是感到十分的吃力,很容易出现逻辑上的问题。

读取信息我采用了BufferedReader, BufferedReeader

buf = new BufferedReader(new

InputStreamReader(client.getInputStream()));的方式将字节输入流转化为字符流,通过buf.readline的方法一行一行地读取信息,虽然能实现功能,但一定不是最优的。

结合I/O的部分来看,这里也许用ObjectOutputStream,采取对象流的方式来进行输入输出的效率最高,可以建立一个用户user的类,输入输出的时候以对象的形式发送,这样在处理用户信息时候应该会带来极大的便利,也比我采用的方式更简洁明了的多。当然对象流在运用时还会遇到对象序列化的问题,这点以后我会再单独梳理。

关于I/O还有一点想说的就是各种流的关闭很重要,尤其牵扯到很多线程的时候,处理不当会一直报错。这让我头疼了很久。

socket套接字其实很简单只是我一开始对它不熟悉,所以觉得用起来云里雾里,说穿了无非就是服务器构建一个serversocket,并且打开一个端口,然后server.accept在该端口等待客户的链接就可以了,考虑到多用户的登录,可以用

boolean flag=true;
while(flag){
server.accept;
new Thread(new xxx()).start();
......
}

类似如此的方法,设立标志位,循环接受用户的链接,并开启多线程就可以了。

类集和多线程是最最让我头疼的地方,在如何灵活运用诸如Hashmap等类集的时候感觉问题蛮多的,我最后也仅仅采取了static

Listsocket = new
ArrayList();
socket.add(client);的方法来保存所有的链接成员,并用
for(int i
=0;i
PrintStream(socket.get(i).getOutputStream());
pt.println(name+":
"+str);
}

的方式向所有用户发送信息,来实现群聊的功能。但是这在处理实时跟新在线人员列表的时候感觉力不从心,我到最后也没有实现显示所有在线成员的功能,最多做到提示上下线。当然了,这在很大程度上是受到了打印流的局限。

多线程我到现在依然还是比较混乱的,到我真正有较深理解后再做梳理。

最后说下JDBC,我做的聊天室实现了注册的功能,将注册信息保存在数据库的表内,

buf = new BufferedReader (new
InputStreamReader(client.getInputStream()));
boolean
flag=true;
while(flag){
String
name= buf.readLine();
String
password=buf.readLine();
System.out.println(name);
System.out.println(password);
String
str1= "SELECT id,name,password "+" FROM data WHERE name LIKE
?";
Class.forName(DBDRIVER);
con
=DriverManager.getConnection(DBURL, DBUSER, DBPASS);
pst=con.prepareStatement(str1);
pst.setString(1,
"%"+name+"%");
rs
=pst.executeQuery();
if(rs.next()){
pt.println("0");
}else{
pt.println("1");
String
str2 = "INSERT INTO data(name,password)VALUE(?,?)";
pst1
=con.prepareStatement(str2);
pst1.setString(1,name);
pst1.setString(2,password);
pst1.executeUpdate();
flag=false;
} rs.close();
pst.close();
pst1.close();

具体代码如上,涉及到一些sql语言没什么好说的,还是得靠记忆和经验。涉及数据库有一点是让我很不理解的,就是我在eclipse环境下通过数据库将所有注册用户信息显示在一个jtextarea界面里可以实现,但是为什么把项目导出之后就显示不了了,这我到现在都不理解,非常苦闷。

总的来说从这个项目暴露出我基础不牢固的问题,我在接下去的一周重点会放在基础知识点的回顾上,主要在面向对象,类集,多线程,i/o这几个部分。