qq项目---一对一聊天 能不能在服务器端开个数组存储服务器建立的socket连接? ?? 2.如何实现,如果好友在线,则显示彩色头像,反之,则显示灰色头像??? 当好友在线时,则提示之,并播放提示声音。??? /* 韩老师说的话: 1.一对一聊天 如何进行一个真实的聊天呢??? 首先, 我们先不考虑多人聊天,那么,客户端1能不能把信息直接发送给客户端2呢?? 如果在没优化之前是不会的,但其实真实的qq ,是可以的,并且如果发现通信的双方都在同一个局域网,它可能不走服务器 现在,我们不考虑他们俩个不通过服务器实现通信。 只考虑借助于服务器中转。 那么怎么中转呢??? ::::::: 1.服务器怎么才能把客户端1发来的hello传送给客户端2呢? 那么,服务器的策略是什么呢?? 答: 服务器为了可以完成信息转发, 1.我们可以把服务器得到的每一个socket(和客户端建立的) 保存在Hashmap里面去,并且用一个客户ID去标识该socket。 2.当服务器和某个客户端形成一个连接时(socket),服务器端就单开一个线程,让这个线程与客户端通信。 3.为了服务器能够把客户端1,发来的信息,转发给客户端2,那么这个信息中必须,包含,发送者是谁?接收者是谁? Message { Private String mesType; private String sender; private String getter; private String con; private String sendTime; } \ 在发送者哪一方,做好消息的封装 if(arg0.getSource()==jb) { //如果用户点击了,发送按钮 Message m=new Message(); m.setSender(this.ownerId); m.setGettr(this.friendId); m.setCon(jtf.getText()); // 消息封装好之后,就送到套接字流中,传送到服务器 // 把m 发送给服务器 } 还有一点: 如何读取Message ??? :"线程创建之后,一定要记得启动!" 最为挠头的一点,那就是: 让服务器转发? 怎么让一号发给2号的信息,转发给2号? ::::: 1号发给2号的信息拿到之后,最关键的就是 要知道 2号和服务器达成的这个socket在哪里?? 那么怎么定位这个socket呢??? 解答: 我们回到服务器端,因为转发的任务是在服务器端完成的,不是在客户端, 所以,我们要回到线程处, 即: 在run()函数内,我们能直接取得,客户端2和服务器 建立的socket ,那么我们从哪里取呢? 那么,我们来看这一句话, “我们可以把服务器得到的每个Socket保存在Hashmap中,用用户的Id标识该Socket” 怎么理解这句话??? :::::再创建一个类,用于管理客户端的线程 : 因为我们拿到客户端的线程的话,我们就能拿到这个线程里面的Socket ::: 注意:需要把HashMap 做出静态的。 import java.util.*; public class ManageClientThread { public static HashMap hm=new HashMap(); // 向hm中添加一个客户端通信线程 public void addClientThread(String uid,ClientThread ct) { hm.put(uid,ct); } // public SerConClientThread getClientThread(String uid) { return (SerConClientThread)hm.get(uid); } } 那么,在服务器端,如何利用这个HashMap 呢? 看: // 在服务器端为客户端单开一个线程,并把它划入到线程管理类SerConClientThead的管理范围中, SerConClientThread scct=new SerConClientThread(s); ManageClientThread.addClientThread(uid=u.getUserId(),scct); scct.start(); 那么下面我就完成转发: 我的疑问:??? 1.线程管理类的作用是什么?? 我们为什么要定义线程管理类??? 2.我们利用线程管理类能得到什么?? 3.我们是不是需要要在run()方法内定义 数据的发送? SerConClientThread 的作用是什么??? 在 线程管理类中:如下; Public class SerConClientThread extends Threads { // 为线程类添加,我们需要的属性成员。 // 添加Socket成员 Socket s=null; // SerConClientThread(Socket s) { // 把服务器新生成的Socket连接,赋给线程 this.s=s; } public void run() { while(true) { // 这里该线程可以接受客户端的信息 try{ ObjectInputStream ois =new ObjectInputStream(s.getInputStream()); Message m=(Message)ois.readLine(); // 完成转发 // 取得接收接收人的通信线程 SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter()); ObjectInputStream oos=new ObjectInputStream(sc.s.getOutputStream()); oos.write(m); }catch() { } } } } 我们首先要明确一点: 就是: 线程其本质是类: 那么,线程既然是类,那么他有哪些属性呢?? 他有提供哪些管理这些属性的方法呢??? 我们是不是可以在线程类中定义:socket属性。 记住:线程是位于服务器端的。 每次有一个连接,服务器就生成一个线程对象来与该客户端通信。 所以,线程是开在服务器端,是属于服务器的。 所以,线程也就可以获取服务器所拥有的一些东西。 */
java实现一对一聊天_Java学习笔记------一对一聊天功能----
最新推荐文章于 2021-02-24 06:50:05 发布