论坛首页 Java企业应用论坛

多用户的P2P在线聊天程序,完全源码 连载三 编写监听用户信息类

浏览 2254 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2010-03-15   最后修改:2010-03-16

本例开发实现了一个多用户的P2P在线聊天程序,C/S结构,客户端可发送消息,然后其他的用户接收到该消息并将其显示在界面中,服务器对信息进行有关处理并向适当的用户发送,同时在服务器端还将显示所有的在线用户,网络管理员即服务器端管理员可选中某用户并将其踢出该聊天室。

本篇为第二篇,如果您是第一次进来请从第一篇开始,此程序不用修改完全可用,第一篇地址:http://java161.iteye.com/blog/616113

 


3 编写监听用户信息类(UserThread.java)

  在监听用户信息类中,首先需要实例化一个Socket输入流来读取从客户端发送过来的信息,然后根据该信息进行相应的处理:

   protected DataInputStream inStream;

   inStream=new DataInputStream(connSock.getInputStream());

   其中connSock为Socket连接的实例。

  

同时该类还应该得到该用户所在的IP地址及该用户的登陆用户名等信息,从而使网络管理员可以很方便地对聊天室中的该用户进行管理。得到客户端IP的程序如下所示:

   String userIP="";

   InetAddress inet=connSock.getInetAddress();

   userIP=inet.getHostAddress();

 

  然后该类可以从输入流中读取有关数据:

  String str=inStream.readUTF();

  得到客户的输入数据后则可以对该数据进行分析,在本次开发中利用“:%:”作为分隔符,对得到的字符串进行分析:

   StringTokenizer st=new StringTokenizer(str,":%:");

   String key=st.nextToken();

   if(key.equals("login"))

   {

      userName=st.nextToken();

      server.list1.addItem(userIP+"---"+userName);

   }

   else if(key.equals("quit"))

        {

           server.list1.remove(userIP+"---"+userName);

           server.removeServerConn(userIP,userName);

           stop();

        }

       else

          server.tellEveryone(str);

   对上面的程序进行分析,用户监听线程得到从客户端传送过来的数据,然后利用StringTokenizer类进行分析得到数据的主关键字key为“login”表示该客户为新登陆用户,则继续得到该信息中所包含的用户登录名,同时将该用户的IP地址和其用户名同时显示到主窗口中,其中Server为主窗口对象的实例句柄,list1为主窗口中的一个列表框,它用来记录当前所有的客户用户名和IP地址。

   若 key 为“quit”表示客户端用户退出的通知,则需要在主界面中将该用户删除,同时将该用户的实例从矢量表中删除,调用主窗口类中的removeServerConn()方法实现。该方法实现如下所示:

   void removeServerConn(String ip,String userName)

    {

        for(int i=0;i<=users.size();i++)

        {

            ServerConn conn=(ServerConn)users.elementAt(i);

           String ip1=conn.reader.userIP;

           String userName1=conn.reader.userName;

           if(ip.equals(ip1)&&userName.equals(userName1))

           users.removeElement(conn);

        }

    }

   users为在主窗体对象中定义的一个矢量表,用来存放一共有多少个客户实例,它存储的是ServerConn对象。

   若key是客户端所发送过来的信息,需要将其发送给该聊天室中的其他所有成员,则需要调用主函数中的tellEveryone()函数:

  void tellEveryone(String str)

    {

        for(int i=0;i<=users.size();i++)

        {

            ServerConn conn=(ServerConn)users.elementAt(i);

            conn.sendString(str);

        }

}

tellEveryone()函数将逐项得到当前聊天室中所有的客户实例,然后分别向它们发送指定的信息。

在这用到了一个很重要的类:StringTokenizer 类。

StringTokenizer 类可以将指定的字符串分解成为标识,它依靠一系列的分隔符来识别标识。它的构造函数有以下三种:

l         public StringTokenizer(Sring str);

l         public StringTokenizer(Sring str,String delim);

l         public StringTokenizer(Sring str,String delim,boolean returnTokens);

其中参数:

l         Sring str—————————需要分解的字符串;

l         String delim———————指定的分隔符字符串;

l         boolean returnTokens——指定返回时是否包含指定的分隔符, returnTokens为true,返回字符串时将包含该分隔符,

returnTokens为false,返回字符串时将忽略该分隔符。

下面列出StringTokenizer 类包含的所有方法:

?         countTokens()—————————返回还有多少可用的标识

?         hasMoreElements()———————测试在使用nextToken()前是否还有标识

?         hasMoreTokens()————————同hasMoreElements()

?         nextElement()—————————返回字符串中下一个标识

?         nextToken()——————————同nextElement()

?         nextToken(String newDelim)—返回字符串的下一个标识,但重新指定分隔符

 

程序清单

 

package Server;

import java.awt.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.lang.*;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2010</p>
 *
 * <p>Company: </p>
 *
 * @author www.jianfei5u.com
 * @version 1.0
 */
public class UserThread extends Thread {
 protected Socket connectionSocket;
 protected DataInputStream inStream;
 SimpleServer server;
 String userIP = "";
 String userName = "";

 public UserThread(SimpleServer server, Socket connSock) throws IOException {
  InetAddress inet = connSock.getInetAddress();
  userIP = inet.getHostAddress();
  connectionSocket = connSock;
  this.server = server;
  inStream = new DataInputStream(connSock.getInputStream());
 }

 protected void closeConnection() {
  try {
   connectionSocket.close();
  } catch (Exception oops) {
  }
  stop();
 }

 public void run() {
  while (true) {
   try {
    String str = inStream.readUTF();
    StringTokenizer st = new StringTokenizer(str, ":%:");
    String key = st.nextToken();
    if (key.equals("login")) {
     userName = st.nextToken();
     server.list1.addItem(userIP + "---" + userName);
    } else if (key.equals("quit")) {
     server.list1.remove(userIP + "---" + userName);
     server.removeServerConn(userIP, userName);
     stop();
    } else
     server.tellEveryone(str);
   } catch (Exception oops) {
   }//end of try
  }//end of while
 }//end of public
}//end of class

 

未完待续。。。下篇

http://java161.iteye.com/blog/616657

Client端  编写客户端Applet

   发表时间:2010-03-16  
多用户的P2P在线聊天程序,终于完成

多用户的P2P在线聊天程序,完全源码 连载一 监听新用户加入

多用户的P2P在线聊天程序,完全源码 连载二 编写用户实例类

多用户的P2P在线聊天程序,完全源码 连载三 编写监听用户信息类

多用户的P2P在线聊天程序,完全源码 连载四 编写客户端Applet类

多用户的P2P在线聊天程序,完全源码 连载五 编写客户端用户监听线程

多用户的P2P在线聊天程序,完全源码 连载六 通信流程(实例P2P原理分析图)和运行结果
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics