该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-03-15
最后修改:2010-03-15
本例开发实现了一个多用户的P2P在线聊天程序,C/S结构,客户端可发送消息,然后其他的用户接收到该消息并将其显示在界面中,服务器对信息进行有关处理并向适当的用户发送,同时在服务器端还将显示所有的在线用户,网络管理员即服务器端管理员可选中某用户并将其踢出该聊天室。以上功能的完成主要分为以下几个步骤。
开发环境Eclipse3.2 —— Java开发的IDE工具,用于编写服务端和客户端的功能实现类。
一 Server端
1 监听新用户加入(SimpleServer.java)
新建-〉工程(名为Chat),新建包(名为Server),新建File,名为SimpleServer.java。 在该类中,首先创建一Frame对象,而后再Frame类中添加两个按钮button1(“关闭”)和button2(“踢出”),一个列表框list1以及一个组合框groupBox1,并利用paneLayout进行适当的布局。完成main函数用来显示主窗体对象: public static void main(String[] args) { try { SimpleServer simpleServer=new SimpleServer(4321); simpleServer.setLocation(100,50); simpleServer.setSize(400,300); simpleServer.show(); } catch(Exception e) { System.out.print("GotError"); e.printStackTrace() ; } } 在主程序中创建一个无限循环,用来监听指定端口查看是否有新的用户加入到聊天室,每监听到一个新的用户则初始化建立一个Socket连接,并作为一个单独的线程保持与该用户的所有联系。 首先定义个ServerSocket,ServerSocket就是服务器端的Socket,它可以监听客户端的连接,而同普通Socket不同就是它的实例化不需要指定主机名而只需要执行特定的端口(若不指定系统就会自动赋予)就可以了: try { protected ServerSocket listenSock; int listenPort=4321; listenSock=new ServerSocket(listenPort); }
catch(Exception e) { System.out.println(e.toString()); } 在服务器端已经初始化了一个4321端口用来监听客户端所发送过来的信息,但必须确定服务器该端口是否可用,如果该端口已经被占用则将抛出一个异常而导致该端口初始化失败。初始化该端口之后,则可以加入一个无限循环用来监听消息: public void waitForClients() { while(true) { try { Socket newClient=listenSock.accept() ; newConn=new ServerConn(this,newClient); users.addElement(newConn); } catch(Exception bad) { bad.printStackTrace() ; } } } 当服务器监听到一个新的客户加入时,便同客户端建立一个Socket连接,同时实例化一个用来控制该用户的实例ServerConn,并将该用户实例加入一个矢量表中,该矢量表存放所有的用户实例对象。
在该实例中网络管理员可以在服务器端对聊天中的在线成员进行简单的维护,也就是可以强制将该用户踢出聊天室。在主窗体中的button2的实现方法如下所示: void button2_actionPerformed(ActionEvent e) { String str=list1.getSelectedItem(); StringTokenizer st=new StringTokenizer(str,"---"); String userIP=st.nextToken(); String userName=st.nextToken(); 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(userIP.equals(ip1)&&userName.equals(userName1)) { list1.remove(str); conn.sendString("quit"); conn.reader.stop(); users.removeElement(conn); } } } 通过循环确定当前网络管理员在列表中所选择的用户实例,然后向该用户发送“quit”指令,该指令在客户端将解释执行并强制将该用户从聊天室中踢出;同时服务器端该用户线程停止,用户列表中删除该用户并将该用户实例从矢量表中删除。
最后得到主窗体如程序清单SimpleServer.java所示。 package Server; import java.awt.*; /**
public void waitForClients() public synchronized String processString(String instr) public static void main(String[] args) public SimpleServer() private void jbInit() throws Exception { groupBox1.setLayout(paneLayout2); button1.setLabel("关闭"); groupBox1.add(list1,new PaneConstraints("list1","list11", void tellEveryone(String str) void removeServerConn(String ip,String userName) } void button2_actionPerformed(ActionEvent e)
void button1_actionPerformed(ActionEvent e) SimpleServer_button2_actionAdapter(SimpleServer adaptee) public void actionPerformed(ActionEvent e) class SimpleServer_button1_actionAdapter implements java.awt.event.ActionListener SimpleServer_button1_actionAdapter(SimpleServer adaptee) public void actionPerformed(ActionEvent e)
未完待续。。。 下一集 编写用户实例类 地址 http://java161.iteye.com/blog/616123 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-03-16
|
|
返回顶楼 | |
发表时间:2010-03-16
好贴 正好学习下 CS和多线程 通信技术
先去面试 晚上回来看 |
|
返回顶楼 | |
发表时间:2010-03-16
用组播可以去掉服务器端
|
|
返回顶楼 | |
发表时间:2010-03-16
wujiazhao88 写道 用组播可以去掉服务器端
组播不可以在广域网上跑,去研究下组播吧。 |
|
返回顶楼 | |
发表时间:2010-03-17
建议楼主以后发代码的时候至少写上注释,还有最好将源码文件打包上传,还有最好画流程图,还有就算懒得画流程图,那么画个思路图也可以啊。
习惯啊,同学们! |
|
返回顶楼 | |
发表时间:2010-03-17
提点意见先.
代码注释 代码样式 |
|
返回顶楼 | |
发表时间:2010-03-17
随便看了下,没看出来哪里用到了P2P。
server没有线程池的管理? 长链接可以考虑NIO实现。 |
|
返回顶楼 | |
发表时间:2010-03-17
哥们你整理好弄一个包上传上,加上注释,
原理分析图片看不见是不是上传的原理 |
|
返回顶楼 | |
发表时间:2010-03-27
我觉得代码里面有些变量的命名不是很清楚,意思不明确。
|
|
返回顶楼 | |
浏览 7412 次