基于JAVA的ICQ系统的设计于实现

基于JAVAICQ系统的设计于实现

一.序言
ICQ
是英文"I seek you "的简称,中文意思是我找你。ICQ最大的功能就是即时信息交流,只要记得对方的号码,上网时可以呼他,无论他在哪里,只要他上网打开ICQ,人们就可以随时交流。ICQ源于以色列特拉维夫的Mirabils公司。该公司成立于1996年7月,也就是在这个时候,互联网上最出名,下载使用人数最多的免费软件ICQ诞生了。可能是其不断增加的用户和广阔的前景以及广泛的应用前景和巨大的市场潜力,MirabilsICQ最终被美国在线AOL收购。由于ICQ的成功,推动了ICQ的本土化,就中文的ICQ而言,现在已经越来越多,比如著名的深圳腾迅公司推出的OICQ(现在由于版权问题,已改名为QQ2001),还有由TOM.COM推出的Tomq等,这些软件技术都很好,而且简单易用,成为中国网民最喜欢的通信软件。

但是这些公司都只提供软件的客户端程序免费下载,而不提供其服务器程序,因此对于未与互联网连接的私有网络,这些软件就用不上了。当然网上也有免费的类似ICQ的服务器提供下载,但是好多都不提供源程序,即使有,其说明也很简单,我很想知道它是怎么回事,所以我就试着做了。

二.设计

1.数据库设计
系统可以采用任何一种流行的,Java支持的数据库,本系统采用了Microsoft公司的access作为后台数据库。通过对现在流行的一些Icq的参考,建立数据库,名为javaicq,数据库共建立两个表,一个是用户的基本信息,包括呢称,Jicq号码等。一个是用户的好友表,包括用户自己的号码和好友的号码。

(1)用户的基本信息表(表名icq)

序号            字段名                        含义                                        数据类型                  NULL

1                 Icqno                          用户的号码                              Int                            No

2                 Nickname                    用户的呢称                              Char                        No

3                 Password                    用户的密码                              Char                        No

4                 Status                         用户在线否                              Bit                           No

5                 Ip                                用户的IP地址                          Char                        Yes

6                 Info                             用户的资料                              Varchar                    Yes

7                 Pic                             用户的头像号                           Int                            Yes

8                 Sex                            用户性别                                  Char                        Yes

9                 Email                          用户的email                            Char                        Yes

10               Place                          用户的籍贯                              Char                        yes

其中Icqno字段为自动增加。(其他还可以添加诸如电话号码等字段作为更多选择)

2)用户的好友表(表名friend

序号               字段名                   含义                                    数据类型                      NULL

1                   Icqno                     用户的号码                          Int                                No

2                   Friend                   好友的号码                          Int                                No

 

3.系统模式及程序(具体程序参看源程序)
系统采用客户/服务器摸式(如图)

 

1.       服务器程序:

服务器与客户间通过套接口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();}//捕或异常
     
     
    }
     
     
  }//服务器程序结束

 

2.       客户程序如下(部分)

客户通过Socket(InetAddress,port)建立与服务器的连接。服务器与客户都通过构造BufferedReader,PrintWriter来建立输入输出流,然后双方通过该输入输出流来相互传递信息,一旦收到客户方的连接请求,服务器accept()方法返回一个新建的Socket对象。客户端然后向服务器发送消息,比如注册,登录,查找好友等,服务器收到来自客户的请求后,针对不同的消息处理请求, 虽然UDP不可靠但是对于icq可靠性并不太重要,而且UDP快速,所以客户间发送信息通过UDP。用户登录时通过类DatagramPacketDatagramSocket创建UDP包括其本地接受端口以及发送端口,默认端口为50005001,通过取得的好友的IP地址来向好友发送消息(send(DatagramPacket)和接受消息(receive(DatagramPacket))。当用户通过UDP收到消息后,可以通过DatagramPacket的方法InetAddress getAddress()得到对方的ip地址,通过对好友列表比较以判断是谁并提示用户收到某某的消息,然后用户选择该用户查看消息,如果好友列表没有该人就显示收到陌生人的消息。用户可以按陌生人按钮查看消息。

1.       用户注册。当服务器收到用户的注册请求,便开始接受客户传第的信息,诸如客户的呢称啦,性别,籍贯,头像,个人资料等,接受完毕后,便通过JdbcOdbc与后台数据库连接,然后向数据库添加记录,如果成功,便向客户返回其Jicq号码,并在数据库中注册用户的IP地址,然后更新其Status1即用户在线。客户收到服务器返回的信息后,便打开主程序窗口,并同时开始创建UDP以便在用户之间建立联系。

******部分程序如下:

 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){}
     
     
    }
     
     
   }


2.       用户登录。在客户端,用户输入其jicq号码和密码,然后建立与服务器的连接,告诉服务器我要登录,服务器收到后,开始通过JdbcOdbc读取数据库,然后与用户输入的信息比较,如果相同就向客户返回成功消息并将其Status字段设为1表示上线了以及注册其IP地址,否则返回错误,如果客户收到成功信息就打开主窗口,否则提示出错。如果成功,便打开主程序窗口,并同时开始创建UDP以便在用户之间建立联系。然后客户向服务器请求读取好友名单,服务器收到该请求,开始读取数据库中的friend表,得到好友的号码后,再在icq表中读取好友资料,然后向客户端发送这些信息,客户收到后就在主窗口显示好友,比如头像,呢称。并且建立几个矢量(Vector)用以存储好友的呢称,jicq号码,头像编号,ip地址等信息。

部分程序如下:(程序流程图与注册差不多,)

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){}
     
     
  }

 

3.       用户添加好友。客户登录后,按查找按钮后,开始向服务器发出查找请求,服务器读取数据库表icq并向客户返回其结果,客户收到后在查找窗口中显示,如果用户选择了一个好友,就向服务器发送添加好友请求,服务器收到后就向数据库表friend中添加自己的号码以及好友的号码,并从icq表中读取其基本信息返回给客户端,然后客户收到并在主窗口显示该好友。并且通过UDP通知该客户,对方收到该消息后,可以选择添加该用户为好友或者不。(程序流程图与程序略,参看源程序)

4.       用户删除好友。用户在其好友列表中选择要删除的好友并按删除,然后向服务器发送删除请求,服务器收到该请求后,连接数据库表friend删除用户及该好友的记录,如果成功就向客户返回成功消息,客户收到后在其好友列表中删除该好友。(程序流程图与程序略,参看源程序)

5.       用户发送和接收消息.用户通过在好友列表里的好友的ip地址,通过UDP与其他用户进行信息交流, (程序流程图与程序略,参看源程序src.zip)及部分程序运行结果界面图pic.zip

三.程序界面
程序界面主要参考腾迅公司的QQ2000,在实现时采用的JavaSwing图形包。开发工具用的是Borland公司的Jbuilder4

四.程序的使用
源程序参见 src.zip.
部分程序运行结果界面图pic.zip.

1.       服务器端:(Windows平台)首先应有java环境jdk,建议采用jdk1.3。然后应有一个数据库系统,建立数据库javaicq,并且建立表icq和表friend。然后在控制面板中的ODBC数据源中设置数据源javaicq建立与数据库的连接。然后运行javac Server.java ,java Server及可。

2.       客户端:只要有有java环境jdk就可以建议jdk1.3。然后运行javac New.java ,java New及可。

五.参考资料:

  • Java2图形设计 卷二:Swing () David M.Geary
  • Java2 编程思想 () Bruce Eckel

·         UNIX网络编程(第一卷)() W.Richard Stevens

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统采用客户/服务器摸式服务器与客户间通过套接口Socket(TCP)连接。在java中使用套接口相当简单,Java API为处理套接口的通信提供了一个类java.net.Socket.,使得编写网络应用程序相对容易.服务器采用多线程以满足多用户的请求,通过JDBC与后台数据库连接,并通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为8080,然后无限循环调用accept()方法接受客户程序的连接客户通过Socket(InetAddress,port)建立与服务器的连接。服务器与客户都通过构造BufferedReader,PrintWriter来建立输入输出流,然后双方通过该输入输出流来相互传递信息,一旦收到客户方的连接请求,服务器accept()方法返回一个新建的Socket对象。客户端然后向服务器发送消息,比如注册,登录,查找好友等,服务器收到来自客户的请求后,针对不同的消息处理请求, 虽然UDP不可靠但是对于icq可靠性并不太重要,而且UDP快速,所以客户间发送信息通过UDP。用户登录时通过类DatagramPacket和DatagramSocket创建UDP包括其本地接受端口以及发送端口,默认端口为5000和5001,通过取得的好友的IP地址来向好友发送消息(send(DatagramPacket)和接受消息(receive(DatagramPacket))。当用户通过UDP收到消息后,可以通过DatagramPacket的方法InetAddress getAddress()得到对方的ip地址,通过对好友列表比较以判断是谁并提示用户收到某某的消息,然后用户选择该用户查看消息,如果好友列表没有该人就显示收到陌生人的消息。用户可以按陌生人按钮查看消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值