精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-15
最后修改:2010-03-16
本例开发实现了一个多用户的P2P在线聊天程序,C/S结构,客户端可发送消息,然后其他的用户接收到该消息并将其显示在界面中,服务器对信息进行有关处理并向适当的用户发送,同时在服务器端还将显示所有的在线用户,网络管理员即服务器端管理员可选中某用户并将其踢出该聊天室。 本篇为第二篇,如果您是第一次进来请从第一篇开始,此程序不用修改完全可用,第一篇地址:http://java161.iteye.com/blog/616113
在监听用户信息类中,首先需要实例化一个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.*; /** public UserThread(SimpleServer server, Socket connSock) throws IOException { protected void closeConnection() { public void run() {
未完待续。。。下篇 http://java161.iteye.com/blog/616657 Client端 编写客户端Applet类 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-16
|
|
返回顶楼 | |
浏览 2254 次