基于JAVA的ICQ系统的设计于实现内容:一.序言二.设计三.程序界面四.程序的使用参考资料关于作者何刚(he_gum@chinaren.com)2001年10月分析ICQ系统,并尝试用Java编写。一.序言ICQ是英文Iseekyou的简称,中文意思是我找你。ICQ最大的功能就是即时信息交流,只要记得对方的号码,上网时可以呼他,无论他在哪里,只要他上网打开ICQ,人们就可以随时交流。ICQ源于以色列特拉维夫的Mirabils公司。该公司成立于1996年7月,也就是在这个时候,互联网上最出名,下载使用人数最多的免费软件ICQ诞生了。可能是其不断增加的用户和广阔的前景以及广泛的应用前景和巨大的市场潜力,Mirabils的ICQ最终被美国在线AOL收购。由于ICQ的成功,推动了ICQ的本土化,就中文的ICQ而言,现在已经越来越多,比如著名的深圳腾迅公司推出的OICQ(现在由于版权问题,已改名为QQ2001),还有由TOM.COM推出的Tomq等,这些软件技术都很好,而且简单易用,成为中国网民最喜欢的通信软件。但是这些公司都只提供软件的客户端程序免费下载,而不提供其服务器程序,因此对于未与互联网连接的私有网络,这些软件就用不上了。当然网上也有免费的类似ICQ的服务器提供下载,但是好多都不提供源程序,即使有,其说明也很简单,我很想知道它是怎么回事,所以我就试着做了。二.设计1.为什么选择JAVA?Java是SunMicrosystem公司的JamesGosling开发的编程语言。它以C++为基础,但是却是一个全新的软件开发语言。Java是一个简单,面象对象,分布式,解释性,强壮,安全,与系统无关,可移植,高性能,多线程和动态的语言-------这是Sun给Java的定义。Sun公司的口号就是网络就是计算机,Java能使所有东西从桌面计算平稳的转变为基于网络的计算,它是专门为此而建立的,并显然是为了完成这个任务而来的。使用Java,我们可以相对轻松的一天编写一个有条理的网络程序。今天,Java的网络功能正在飞跃发展,不断有新的特性增加到这个有价值的基础上,JavaSoft实验室正在不断努力使Java更加完善。2.数据库设计系统可以采用任何一种流行的,Java支持的数据库,本系统采用了Microsoft公司的SQLServer2000作为后台数据库。通过对现在流行的一些Icq的参考,建立数据库,名为javaicq,数据库共建立两个表,一个是用户的基本信息,包括呢称,Jicq号码等。一个是用户的好友表,包括用户自己的号码和好友的号码。(1)用户的基本信息表(表名icq)序号字段名含义数据类型NULL1Icqno用户的号码IntNo2Nickname用户的呢称CharNo3Password用户的密码CharNo4Status用户在线否BitNo5Ip用户的IP地址CharYes6Info用户的资料VarcharYes7Pic用户的头像号IntYes8Sex用户性别CharYes9Email用户的emailCharYes10Place用户的籍贯Charyes其中Icqno字段为自动增加。(其他还可以添加诸如电话号码等字段作为更多选择)(2)用户的好友表(表名friend)序号字段名含义数据类型NULL1Icqno用户的号码IntNo2Friend好友的号码IntNo3.系统模式及程序(具体程序参看源程序)系统采用客户/服务器摸式(如图)1.服务器程序:服务器与客户间通过套接口Socket(TCP)连接。在java中使用套接口相当简单,JavaAPI为处理套接口的通信提供了一个类java.net.Socket.,使得编写网络应用程序相对容易.服务器采用多线程以满足多用户的请求,通过JDBC与后台数据库连接,并通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为8080,然后无限循环调用accept()方法接受客户程序的连接服务器程序代码如下:(部分)importjava.io.*;importjava.net.*;importjava.sql.*;importjava.util.Vector;classServerThreadextendsThread{//继承线程privateSocketsocket;//定义套接口privateBufferedReaderin;//定义输入流privatePrintWriterout;//定义输出流intno;//定义申请的jicq号码publicServerThread(Sockets)throwsIOException{//线程构造函数socket=s;//取得传递参数in=newBufferedReader(newInputStreamReader(socket.getInputStream()));//创建输入流out=newPrintWriter(newBufferedWriter(newOutputStreamWriter(socket.getOutputStream())),true);//创建输出流start();//启动线程}publicvoidrun(){//线程监听函数try{while(true){Stringstr=in.readLine();//取得输入字符串if(str.equals(end))break;//如果是结束就关闭连接elseif(str.equals(login)){//如果是登录try{Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);//连接数据库Connectionc=DriverManager.getConnection(jdbc:odbc:javaicq,,);Stringsql=selectnickname,passwordfromicqwhereicqno=?;//准备从数据库选择呢称和密码PreparedStatementprepare=c.prepareCall(sql);//设定数据库查寻条件Stringicqno=in.readLine();intg=Integer.parseInt(icqno);//取得输入的jicq号码System.out.println(icqno);Stringpasswd=in.readLine().trim();//取得输入的密码System.out.println(passwd);prepare.clearParameters();prepare.setInt(1,g);//设定参数ResultSetr=prepare.executeQuery();//执行数据库查寻if(r.next()){//以下比较输入的号码于密码是否相同Stringpass=r.getString(password).trim();System.out.println(pass);if(passwd.regionMatches(0,pass,0,pass.length())){out.println(ok);//如果相同就告诉客户ok//并且更新数据库用户为在线//以及注册用户的ip地址//*************registeripaddressStringsetip=updateicqsetip=?whereicqno=?;PreparedStatementprest=c.prepareCall(setip);prest.clearParameters();prest.setString(1,socket.getInetAddress().getHostAddress());prest.setInt(2,g);intset=prest.executeUpdate();System.out.println(set);//*************ipaddress//setstatusonlineStringstatus=updateicqsetstatus=1whereicqno=?;PreparedStatementprest2=c.prepareCall(status);prest2.clearParameters();prest2.setInt(1,g);intset2=prest2.executeUpdate();System.out.println(set2);//setonline}//否者告诉客户失败elseout.println(false);r.close();c.close();}else{out.println(false);System.out.println(false);r.close();c.close();}}catch(Exceptione){e.printStackTrace();}socket.close();}//endlogin//登录结束//以下为处理客户的新建请求elseif(str.equals(new)){try{Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);//连接数据库Connectionc2=DriverManager.getConnection(jdbc:odbc:javaicq,,);Stringnewsql=insertintoicq(nickname,password,email,info,place,pic)values(?,?,?,?,?,?);//准备接受用户的呢称,密码,email,个人资料,籍贯,头像等信息PreparedStatementprepare2=c2.prepareCall(newsql);Stringnickname=in.readLine().trim();Stringpassword=in.readLine().trim();Stringemail=in.readLine().trim();Stringinfo=in.readLine().trim();Stringplace=in.readLine().trim();intpicindex=Integer.parseInt(in.readLine());prepare2.clearParameters();prepare2.setString(1,nickname);prepare2.setString(2,password);prepare2.setString(3,email);prepare2.setString(4,info);prepare2.setString(5,place);prepare2.setInt(6,picindex);intr3=prepare2.executeUpdate();//执行数据库添加Stringsql2=selecticqnofromicqwherenickname=?;//以下告诉客户其注册的号码PreparedStatementprepare3=c2.prepareCall(sql2);prepare3.clearParameters();prepare3.setString(1,nickname);ResultSetr2=prepare3.executeQuery();while(r2.next()){//out.println(r2.getInt(1));no=r2.getInt(1);System.out.println(no);}out.println(no);out.println(ok);c2.close();//完毕}catch(Exceptione){e.printStackTrace();out.println(false);}socket.close();}//endnew//新建用户结束//以下处理用户查找好友elseif(str.equals(find)){try{Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);Connectionc3=DriverManager