`

通信--多人聊天及画板

    博客分类:
  • java
 
阅读更多
通信总结
我们的目的是做出一个实现通信功能的小项目,这个小项目将要实现以下的功能:
1. 服务器端创建服务器
2. 客户端连接服务器
3. 实现服务器和客户端、客户端与客户端之间的文本通信(即聊天)
4. 实现服务器与客户端、客户端与客户端之间的画图通信(这里以线和圆为例)

这虽然是一个看似简单的通信项目,可要好的实现并不容易。

那么什么叫做“好的实现”?这是个值得深思的问题。有人会说,能够实现你所需要的功能,就算是“好的实现”。这种观点我并不否认,可是,如果一个软件仅仅是能够实现功能,缺少了一定的可再造性,那么,这样的软件一定不是一个值得赞美的软件。
这里我也想来说道一把了。正如胡哥所说,一栋房子,要想建的有多高,绝不取决与民工们板砖的能力,而是取决与设计师们鬼斧神工般的设计!一个软件,就像微信,qq等等,随着时间的推移,不断地在推陈出新更新版本,增加或者完善功能,这就像给一栋大楼加层,要想加得舒坦,那么在设计软件的时候,就应该考虑全面,结构清晰。


㈠ .  “高内聚,低耦合”问题的分析
这里涉及到了一个“高内聚,低耦合”问题。“高内聚,低耦合”是我们要追求的效果,那么什么是“高内聚,低耦合”呢?什么又是“低内聚,高耦合”呢?看看下面的图你就能明白了。
“低内聚,高耦合”:看看下面的图片吧,创建了A,B,C,D四个类,在每个类中又调用了其他的类,这样一来,这四个类的关系就变得错综复杂,就像是一个深院里的大家庭,人与人之间都有着一定的关系,这样一来就组合成了一张极其复杂的关系网,如果A是B的叔叔,C是D的妹妹,A是C的弟弟,请问B的儿子应该喊D什么呢。不用想了,我也不知道,或许这更本就不成立。一个软件,如果是按照上述这种思路编写,那么,别说以后添加、完善功能了,“牵一发则动全身”,这样的代价,恐怕设计师都会被自己吓到,这简直就是天方夜谭。




所以说,我们需要的是一个简明易懂的思路;
“高内聚,低耦合”:看着下面这幅关系图,明显比上面那张图要舒服、清楚的多,这就像一个简单的三口之家,儿子是爸爸妈妈的儿子,爸爸妈妈是儿子的爸爸妈妈,那么儿子的儿子自然是喊爸爸妈妈叫做爷爷奶奶,这样一来,关系变得简单明了得多,而且处理事情也变得容易很多。如果编写软件按照这样的一种思路,类与类之间只是像图示的这种简单的关系,那么我想,要查找错误要更加容易,要完善程序也更加简单,想要添加功能,也不过只是在下面这些简单的线条里多加几条线而已。






弄明白了我们编程的思路,那么接下来,我们不应该急于动手去用代码来完成,而是结合目的,来整理一下程序的整体结构,包括整个程序的板块,有多少类,类里应该有哪些属性,又应该有哪些方法••••

㈡ .通信项目的整体分析
这里,结合上文说的通信小项目,做出如下整体思路分析:
从服务器的角度上:



这是一个大体的思路。本来是想把类中的属性以及方法也一并写上去,可是,后来怎么都觉得在没有实际操作前实在是难以想全应该要有哪些方法和属性,所以我觉得,具体的属性以及方法我们可以等到实际操作的时候在进行写入,以上图示只是给自己提供一个大概的思路,从该图不难看出应该创建几个板块。
客户端:




㈢ .分析关键代码

在整理好编写思路后,我们开始着手用代码解决问题。

① .服务器的创建以及客户端的连接
要实现通信,两个不可或缺的成分分别是服务器和客户端,那么实现服务器的开启与客户端与服务器的连接我们就要靠接下来的几行代码:
ServerSocket server = new ServerSocke(port)
这是实现服务器连接的代码,当然,服务器创建成功后,接下来是等待客户端的连接,代码如下:
Socket client = server.accept();
客户端来连的代码如下
Socket client =new Socket(String address,int port);
这里很容易混淆,在服务器端,等待客户端来连时有一个Socket对象client,而在客户端连接时,又有一个Socket对象client,这两个client有区别么?
答案是毫无疑问的,有区别!前者建立的是服务器与客户端的联系,在获取它的输入输出流以后,输出流表示的是从服务器向客户端写消息,输入流表示的服务器读取客户端的信息;而后者恰恰与前者相反,建立的是客户都啊与服务器的联系,在获取它的输入输出流后,输出流表示的是从客户端向服务器写消息,输入流表示的客户端读取服务器的消息。

②.队列的使用
要实现群聊功能,我们需要把每个客户端与服务器建立的联系的这个对象保存下来,这样,我们用到系统提供的数组队列,并将其封装到一个类中,像这样的类包括Line(线类,保存线),Circle(圆类,保存圆),chatSave(保存客户端与服务器的联系),接下来以chatSave为例:
//创建该类来保存启动的线程用户
public class chatSave {
//创建一个线程数组队列,用static声明,这样其他类中不需要实例化对像就可以使用
private static ArrayList<chatThread> list = new ArrayList<chatThread>();
//写一个将线程对象保存到数组队列中
public static void saveChat(chatThread ct){
System.out.println(" 加入了一个线程对象");
list.add(ct);
}
//移走其中一个线程对象
public static void removeChat(chatThread ct){
System.out.println("删除了一个线程对象");
list.remove(ct);
}
//返回数组中线程对象的数量
public static int getLength(){
return list.size();
}
//得到数组中第I个对象
public static chatThread getChatThread(int i){
return list.get(i);
}
//给数组里所有的线程用户发送信息
public static void chat(String inString) throws IOException{
System.out.println("向所有的客户发送了消息!");
for(int i = 0;i<list.size();i++){
chatThread ct = list.get(i);
ct.sendChat(inString);
}
}
//给数组里所有的线程用户发送线
public static void sendAllLine(int x1,int y1, int x2, int y2){
for(int i = 0;i<chatSave.getLength();i++){
chatThread ct = list.get(i);
ct.sendLine(x1, y1, x2, y2);
}
}
//给数组队列里所有的线程对象用户发送圆
public static void sendAllCircle(int x1,int y1, int x2, int y2){
for(int i = 0;i<chatSave.getLength();i++){
chatThread ct = list.get(i);
ct.sendCircle(x1, y1, x2, y2);
}
}
}
其中sendChat(inString),sendLine(x1, y1, x2, y2),sendCircle(x1, y1, x2, y2)是线程对象中服务器向某一客户端发送文本信息,线信息,圆信息的方法。

③.分隔符的设计
那么要服务器、客户端这些有联系的对象之间交换信息(文本、线、圆),那么如何发送和读取信息是关键,也是就是通信的本质-----协议!怎么才能让接受信息的一段判断得出现在接受的信息是文本信息,还是线信息,还是圆信息?那么又需要做一番精心的设计。
在这里,我做了简单的处理,用最初的一个字节来判断是什么信息,如字节1代表的是文本信息,在发送文本消息时先发送一个“1”,再读取消息时,若最先读到的是“1”,那么可以判定这是文本信息:




/***************************************************************/




这样能够实现对不同种类信息的判断
大家可能也发现了,inString+=“#”;是什么意思。在读取一个文本消息的时候,我们采用的是一个字节一个字节的读取,也就是每次只能读取一个字母,但是我们需要的是字符串,这样的话,我们采用字符串缓冲区寄存的办法,先把读到的每一个 字母放入到字符串缓冲区中,当遇到了一个分隔符(这里是“#”),我们再把这些字母从缓冲区中取出,整合成一个字符串:



解决了以上一系列问题后,整个程序将变得很简单,只要稍微细心,我想,要实现这么一个项目是不难的。
㈣ .成果展示
这里,给大家演示一下群聊功能的实现:





以上是服务器的创建以及客户机的连接;
成功后,可以实现群聊以及发送简单画图的功能:




通过这个小项目的展示,我们可以更加深入地了解到通信操作过程中的核心问题。这只是一个跳板,我们通过这个跳板将可以实现更多的更强大的项目,如五子棋对战等等小游戏平台。
  • 大小: 20.5 KB
  • 大小: 12.7 KB
  • 大小: 68.4 KB
  • 大小: 80.5 KB
  • 大小: 52.9 KB
  • 大小: 77.2 KB
  • 大小: 77.6 KB
  • 大小: 57.1 KB
  • 大小: 73.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics