|
||||
|
||||
|
□您现在的位置: 梧桐细雨范文网 >> 论文中心 >> 计算机类 >> 计算机应用 >> 正文 |
|
|||||
用JAVA制作ICQ | |||||
作者:网络 论文来源:网络 点击数:302 更新时间:2007/3/21 | |||||
分析ICQ系统,并尝试用Java编写。 一.序言 但是这些公司都只提供软件的客户端程序免费下载,而不提供其服务器程序,因此对于未与互联网连接的私有网络,这些软件就用不上了。当然网上也有免费的类似ICQ的服务器提供下载,但是好多都不提供源程序,即使有,其说明也很简单,我很想知道它是怎么回事,所以我就试着做了。 二.设计 1.为什么选择JAVA? Sun公司的口号就是\网络就是计算机\,Java能使所有东西从桌面计算平稳的转变为基于网络的计算,它是专门为此而建立的,并显然是为了完成这个任务而来的。使用Java,我们可以相对轻松的一天编写一个有条理的网络程序。今天,Java的网络功能正在飞跃发展,不断有新的特性增加到这个有价值的基础上,JavaSoft实验室正在不断努力使Java更加完善。 2.数据库设计 (1)用户的基本信息表(表名icq) 序号字段名含义数据类型NULL1Icqno用户的号码IntNo2Nickname用户的呢称CharNo3Password用户的密码CharNo4Status用户在线否BitNo5Ip用户的IP地址CharYes6Info用户的资料VarcharYes7Pic用户的头像号IntYes8Sex用户性别CharYes9Email用户的emailCharYes10Place用户的籍贯Charyes其中Icqno字段为自动增加。(其他还可以添加诸如电话号码等字段作为更多选择)
序号字段名含义数据类型NULL1Icqno用户的号码IntNo2Friend好友的号码IntNo
服务器与客户间通过套接口Socket(TCP)连接。在java中使用套接口相当简单,Java API为处理套接口的通信提供了一个类java.net.Socket.,使得编写网络应用程序相对容易.服务器采用多线程以满足多用户的请求,通过JDBC与后台数据库连接,并通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为8080,然后无限循环调用accept()方法接受客户程序的连接 服务器程序代码如下:(部分) import java.io.*; import java.net.*; import java.sql.*; import java.util.Vector; class ServerThread extends Thread{//继承线程 private Socket socket;//定义套接口 private BufferedReader in;//定义输入流 private PrintWriter out;//定义输出流 int no;//定义申请的jicq号码 public ServerThread(Socket s) throws IOException {//线程构造函数 socket=s;//取得传递参数 in=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建输入流 out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);//创建输出流 start();//启动线程 } public void run(){//线程监听函数 try{ while(true){ String str=in.readLine();//取得输入字符串 if(str.equals(\end\))break;//如果是结束就关闭连接 else if(str.equals(\login\)) {//如果是登录 try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\);//连接数据库 Connection c=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); String sql=\select nickname,password from icq where icqno=?\; //准备从数据库选择呢称和密码 PreparedStatement prepare=c.prepareCall(sql);//设定数据库查寻条件 String icqno=in.readLine(); int g=Integer.parseInt(icqno);//取得输入的jicq号码 System.out.println(icqno); String passwd=in.readLine().trim();//取得输入的密码 System.out.println(passwd); prepare.clearParameters(); prepare.setInt(1,g);//设定参数 ResultSet r=prepare.executeQuery();//执行数据库查寻 if(r.next()){//以下比较输入的号码于密码是否相同 String pass=r.getString(\password\).trim(); System.out.println(pass); if(passwd.regionMatches(0,pass,0,pass.length())){ out.println(\ok\);//如果相同就告诉客户ok//并且更新数据库用户为在线//以及注册用户的ip 地址 //*************register ipaddress String setip=\update icq set ip=? where icqno=?\; PreparedStatement prest=c.prepareCall(setip); prest.clearParameters(); prest.setString(1,socket.getInetAddress().getHostAddress()); prest.setInt(2,g); int set=prest.executeUpdate(); System.out.println(set); //*************ipaddress //set status online String status=\update icq set status=1 where icqno=?\; PreparedStatement prest2=c.prepareCall(status); prest2.clearParameters(); prest2.setInt(1,g); int set2=prest2.executeUpdate(); System.out.println(set2); //set online}//否者告诉客户失败 else out.println(\false\);r.close();c.close();} else{ out.println(\false\); System.out.println(\false\); r.close(); c.close();} }catch (Exception e){e.printStackTrace();} socket.close(); }//end login //登录结束 //以下为处理客户的新建请求else if(str.equals(\new\)){ try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\);//连接数据库 Connection c2=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \);String newsql=\insert into icq(nickname,password,email,info,place,pic) values(?,?,?,?,?,?)\;//准备接受用户的呢称,密码,email,个人资料,籍贯,头像等信息 PreparedStatement prepare2=c2.prepareCall(newsql); String nickname=in.readLine().trim(); String password=in.readLine().trim(); String email=in.readLine().trim(); String info=in.readLine().trim(); String place=in.readLine().trim(); int picindex=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); int r3=prepare2.executeUpdate();//执行数据库添加String sql2=\select icqno from icq where nickname=?\;//以下告诉客户其注册的号码 PreparedStatement prepare3=c2.prepareCall(sql2); prepare3.clearParameters(); prepare3.setString(1,nickname); ResultSet r2=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 (Exception e){e.printStackTrace();out.println(\false\);} socket.close(); }//end new //新建用户结束 //以下处理用户查找好友 else if(str.equals(\find\)){ try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c3=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //以下连接数据库,并且返回其他用户的呢称,性别,籍贯,个人资料等信息 String find=\select nickname,sex,place,ip,email,info from icq\; Statement st=c3.createStatement(); ResultSet result=st.executeQuery(find); while(result.next()){ out.println(result.getString(\nickname\)); out.println(result.getString(\sex\)); out.println(result.getString(\place\)); out.println(result.getString(\ip\)); out.println(result.getString(\email\)); out.println(result.getString(\info\)); }//while end out.println(\over\); ////////GET ICQNO int d,x;boolean y;//以下返回用户的jicq号码,头像号,及是否在线 ResultSet iset=st.executeQuery(\select icqno,pic,status from icq\); while(iset.next()){ d=iset.getInt(\icqno\); out.println(d); x=iset.getInt(\pic\);//pic info out.println(x); y=iset.getBoolean(\status\); if (y){out.println(\1\);} else {out.println(\0\);} //System.out.println(d); } // end send jicqno iset.close(); /////////icqno end c3.close();result.close(); }catch (Exception e){e.printStackTrace();System.out.println(\false\);} //socket.close(); }//end find //查找好友结束 //以下处理用户登录时读取其好友资料 else if(str.equals(\friend\)){ try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c4=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //以下连接好友表,返回用户的好友名单 String friend=\select friend from friend where icqno=?\; PreparedStatement prepare4=c4.prepareCall(friend); prepare4.clearParameters(); int icqno=Integer.parseInt(in.readLine()); System.out.println(icqno); prepare4.setInt(1,icqno); ResultSet r4=prepare4.executeQuery(); Vector friendno=new Vector();//该矢量保存好友号码 while(r4.next()){ friendno.add(new Integer(r4.getInt(1))); } //read friend info //以下告诉客户其好友的呢称,号码,ip地址,状态,头像,个人资料等信息 out.println(friendno.size()); for(int i=0;i<friendno.size();i++){ String friendinfo=\select nickname,icqno,ip,status,pic,email,info from icq where icqno=?\; PreparedStatement prepare5=c4.prepareCall(friendinfo); prepare5.clearParameters(); prepare5.setObject(1,friendno.get(i)); ResultSet r5=prepare5.executeQuery(); boolean status; while(r5.next()){ out.println(r5.getString(\nickname\)); out.println(r5.getInt(\icqno\)); out.println(r5.getString(\ip\)); status=r5.getBoolean(\status\); if (status)out.println(\1\); else {out.println(\0\);} out.println(r5.getInt(\pic\)); out.println(r5.getString(\email\)); out.println(r5.getString(\info\)); } //while r5.close();}//for//发送完毕 out.println(\over\); System.out.println(\over\); c4.close();r4.close(); }catch (Exception e){e.printStackTrace();System.out.println(\false\);} //socket.close(); }//end friend //读取好友信息完毕 //以下处理用户添加好友 else if(str.equals(\addfriend\)){ System.out.println(\add\); try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c6=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //连接数据库,根据接受的用户号码及好友号码向好友表添加记录 int friendicqno=Integer.parseInt(in.readLine()); System.out.println(friendicqno); int myicqno=Integer.parseInt(in.readLine()); System.out.println(myicqno); String addfriend=\insert into friend values(?,?)\; PreparedStatement prepare6=c6.prepareCall(addfriend); prepare6.clearParameters(); prepare6.setInt(1,myicqno); prepare6.setInt(2,friendicqno); int r6=0; r6=prepare6.executeUpdate(); if(r6==1) System.out.println(\ok addfrien\); else System.out.println(\false addfriend\); }catch (Exception e){e.printStackTrace();System.out.println(\false\);} //socket.close(); System.out.println(\over addfriend\); }//end addfriend //用户添加好友结束 //add new friend who add me //以下处理其他用户如果加我,我就加他 else if(str.equals(\addnewfriend\)){ System.out.println(\add\); try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c6=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //连接数据库,根据接受的用户号码及好友号码向好友表添加记录 int friendicqno=Integer.parseInt(in.readLine()); System.out.println(friendicqno); int myicqno=Integer.parseInt(in.readLine()); System.out.println(myicqno); String addfriend=\insert into friend values(?,?)\; PreparedStatement prepare6=c6.prepareCall(addfriend); prepare6.clearParameters(); prepare6.setInt(1,myicqno); prepare6.setInt(2,friendicqno); int r6=0; r6=prepare6.executeUpdate(); if(r6==1) System.out.println(\ok addfrien\); else System.out.println(\false addfriend\); String friendinfo=\select nickname,icqno,ip,status,pic,email,info from icq where icqno=?\; //如果成功,就向用户传递好友的基本信息,比如呢称等 PreparedStatement prepare5=c6.prepareCall(friendinfo); prepare5.clearParameters(); prepare5.setInt(1,friendicqno); ResultSet r5=prepare5.executeQuery(); boolean status; while(r5.next()){ System.out.println(\dsf\); out.println(r5.getString(\nickname\)); out.println(r5.getInt(\icqno\)); out.println(r5.getString(\ip\)); status=r5.getBoolean(\status\); if (status)out.println(\1\); else {out.println(\0\);} out.println(r5.getInt(\pic\)); out.println(r5.getString(\email\)); out.println(r5.getString(\info\)); } //while out.println(\over\); r5.close(); c6.close(); }catch (Exception e){e.printStackTrace();System.out.println(\false\);} System.out.println(\over addnewfriend\); }//end addfriend //结束处理其他用户如果加我,我就加他 //delete friend //以下执行用户删除好友 else if(str.equals(\delfriend\)){ System.out.println(\del\); try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c7=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //连接数据库,根据接受的用户号码及好友号码向好友表删除记录 int friendicqno=Integer.parseInt(in.readLine()); System.out.println(friendicqno); int myicqno=Integer.parseInt(in.readLine()); System.out.println(myicqno); String addfriend=\delete from friend where icqno=? and friend=?\; PreparedStatement prepare7=c7.prepareCall(addfriend); prepare7.clearParameters(); prepare7.setInt(1,myicqno); prepare7.setInt(2,friendicqno); int r7=0; r7=prepare7.executeUpdate(); if(r7==1) System.out.println(\ok delfrien\);//成功 else System.out.println(\false delfriend\);//失败 }catch (Exception e){e.printStackTrace();System.out.println(\del false\);} }//end delete friend //执行用户删除好友结束 //以下处理用户退出程序 else if(str.equals(\logout\)){ try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c8=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //连接数据库,根据接受的用户号码,将其状态字段设为0,及ip地址设为空 int myicqno=Integer.parseInt(in.readLine()); System.out.println(myicqno); String status=\update icq set status=0 , ip=' ' where icqno=?\; PreparedStatement prest8=c8.prepareCall(status); prest8.clearParameters(); prest8.setInt(1,myicqno); int r8=prest8.executeUpdate(); if(r8==1) System.out.println(\ok logout\); else System.out.println(\false logout\); }catch (Exception e){e.printStackTrace();System.out.println(\logout false\);} }//logout end //处理用户退出程序结束 //get who add me as friend //以下处理那些人加了我为好友,以便上线通知他们 else if(str.equals(\getwhoaddme\)){ System.out.println(\getwhoaddme\); try{ Class.forName(\sun.jdbc.odbc.JdbcOdbcDriver\); Connection c9=DriverManager.getConnection(\jdbc:odbc:javaicq\,\ \,\ \); //连接数据库,根据我的号码,从好友表中选择谁加了我 int myicqno=Integer.parseInt(in.readLine()); System.out.println(myicqno); String getwhoaddme=\select icqno from friend where friend=?\; PreparedStatement prepare6=c9.prepareCall(getwhoaddme); prepare6.clearParameters(); prepare6.setInt(1,myicqno); ResultSet r6=prepare6.executeQuery(); Vector who=new Vector(); while(r6.next()){ who.add(new Integer(r6.getInt(1))); }//end while //然后告诉这些好友的ip地址,然后发给用户以便告诉其他客户我上线了 for(int i=0;i<who.size();i++){ String whoinfo=\select ip from icq where icqno=? and status=1\; PreparedStatement prepare=c9.prepareCall(whoinfo); prepare.clearParameters(); prepare.setObject(1,who.get(i)); ResultSet r=prepare.executeQuery(); while(r.next()){ out.println(r.getString(\ip\)); } //while r.close(); }//for out.println(\over\); System.out.println(\over\); c9.close();r6.close(); }catch (Exception e){e.printStackTrace();System.out.println(\false\);} }//end get who add me as friend //处理上线结束 System.out.println(\Echo ing :\+str); } System.out.println(\Close...\); }catch(IOException e){}//捕或异常 finally {try{socket.close();} catch(IOException e){} } }} public class Server{//主服务器类 public static void main(String args[])throws IOException{ ServerSocket s=new ServerSocket(8080);//在8080端口创建套接口 System.out.println(\Server start..\+s); try{ while(true){Socket socket=s.accept();//无限监听客户的请求 System.out.println(\Connectino accept:\+socket); try{new ServerThread(socket);//创建新线程 }catch(IOException e){socket.close();} } }finally{s.close();}//捕或异常 } }//服务器程序结束 客户程序如下(部分) void jButton1_mouseClicked(MouseEvent e) { try{ Socket socket=new Socket(InetAddress.getByName(sername),serverport);//连接服务器 BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out=new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); out.println(\new\);//告诉服务器我要注册 out.println(nickname.getText().trim());//告诉服务器我的呢称,密码,email,资料 out.println(password.getPassword());//以及头像号等信息 out.println(email.getText().trim()); out.println(info.getText().trim()); out.println(place.getSelectedItem()); out.println(headpic.getSelectedIndex());//head picindex int no; no=Integer.parseInt(in.readLine()); //System.out.print(no); String str=\ \; str=in.readLine().trim();//从服务器取得状态 if(str.equals(\false\)) JOptionPane.showMessageDialog(this,\对不起,出错了:- (\,\ok\,JOptionPane.INFORMATION_MESSAGE);//失败就警告 else{//成功就打开主程序 JOptionPane.showMessageDialog(this,\your javaicq#is\+no,\ok\,JOptionPane.INFORMATION_MESSAGE); this.dispose(); MainWin f2=new MainWin(no,sername,serverport); f2.setVisible(true);} //System.out.println(\\\n\); //}while(!str.equals(\ok\)); // socket.close(); }catch(IOException e1){} } } void login_mouseClicked(MouseEvent e) { try{Socket socket=new Socket(InetAddress.getByName(server),serport);//与服务器连接 BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建//输入流 PrintWriter out=new PrintWriter(new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true); //创建输出流 out.println(\login\);//告诉服务器我要登录 out.println(jicq.getText()); //告诉服务器我的号码 out.println(password.getPassword()); //告诉服务器我的密码 String str=\ \; //do{ str=in.readLine().trim();//取得服务器发过来的消息 if(str.equals(\false\)) JOptionPane.showMessageDialog(this,\对不起,出错了:-(\,\ok\,JOptionPane.INFORMATION_MESSAGE);//失败 else{ this.dispose(); int g=Integer.parseInt(jicq.getText()); MainWin f2=new MainWin(g,server,serport);//如果成功就打开主程序 f2.setVisible(true); } //System.out.println(\\\n\); //}while(!str.equals(\ok\)); }catch(IOException e1){} } 用户添加好友。客户登录后,按查找按钮后,开始向服务器发出查找请求,服务器读取数据库表icq并向客户返回其结果,客户收到后在查找窗口中显示,如果用户选择了一个好友,就向服务器发送添加好友请求,服务器收到后就向数据库表friend中添加自己的号码以及好友的号码,并从icq表中读取其基本信息返回给客户端,然后客户收到并在主窗口显示该好友。并且通过UDP通知该客户,对方收到该消息后,可以选择添加该用户为好友或者不。(程序流程图与程序略,参看源程序) 用户删除好友。用户在其好友列表中选择要删除的好友并按删除,然后向服务器发送删除请求,服务器收到该请求后,连接数据库表friend删除用户及该好友的记录,如果成功就向客户返回成功消息,客户收到后在其好友列表中删除该好友。(程序流程图与程序略,参看源程序) 用户发送和接收消息.用户通过在好友列表里的好友的ip地址,通过UDP与其他用户进行信息交流, (程序流程图与程序略,参看源程序src.zip)及部分程序运行结果界面图pic.zip
四.程序的使用 服务器端:(Windows平台)首先应有java环境jdk,建议采用jdk1.3。然后应有一个数据库系统,建立数据库javaicq,并且建立表icq和表friend。然后在控制面板中的ODBC数据源中设置数据源javaicq建立与数据库的连接。然后运行javac Server.java ,java Server及可。 客户端:只要有有java环境jdk就可以建议jdk1.3。然后运行javac New.java ,java New及可。 Java2图形设计卷二:Swing (美) David M.Geary Java2 编程思想(美)Bruce Eckel UNIX网络编程(第一卷)(美)W.Richard Stevens
|
|||||
论文录入:梧桐细雨范文网 责任编辑:梧桐细雨范文网 | |||||
【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
【网友评论】(只显示最新10条。评论内容只代表网友观点,与本站立场无关) |
|
◇网站地址:江苏省大丰市 邮编:224100 ◇本站ICP备案证书:苏ICP备06051753号 ◇本站站长:梧桐细雨 |