由于.net的出现,确实使大量的开发工作,变得更象是英语这样的高级语言。由于面向对象的开发设计,好多原本复杂的操作,只是在组件开发中涉及,对于前台的应用层,就变成仅需调用一个个属性和方法,就可以完成了。比如要添加一个文档,先声明一个Document对象命名为doc,然后给Document的属性赋值:
doc.Name="test";
doc.FileFullName="C:\\test.txt";
之后,调用Document的Add方法:int rl=doc.Add()。这样文档就由组件上传走了。至于是上传到服务器的一个指定的路径,还是用二进制上载至数据库服务器,都只有组件知道了,对于前台开发人员也无须了解。
而这种方式,也是框架代码的擅长之处。之前非常困难的网络通信操作,现在被微软封装在了System.Net和System.Sockets下,对于我们的调用,也变得非常简单。所以写一个即时通信程序,只要我们了解Socket的工作机制,也就完全可以做得出来了。
下面谈一下我的设计思路:
首先是服务端,要创建一个TcpListener,这负责接收由客户端发送过来的通信请求的Socket。
客户端要创建一个TcpClient,然后将要发送的消息转换成流,就可以通过Socket发送给服务端的TcpListener。还要再创建一个TcpListener,这负责接收服务端发送过来的回复消息或转发过来的其它客户端要发送给当前客户端的消息。
这样服务端和客户端就可以互相通信了。
但这样做还远远不够,因为我们需要对传输的流进行解释,通过不同的流的定义,服务端要确定要如何操作。比如登录、注销、发消息、传文件。或者,我要在消息中包含传送给其它客户端的目标地址。而最好的方式,是需要创建一个服务端和客户端都理解的通用对象库,我们不妨命名为MessageBase,在这里定义MessageHeader,MessageBody对象。这样,我们的目标地址就可以写在MessageHeader中了。然后,我们把MessageHeader和MessageBody序列化为二进制,通过Socket进行传输。
服务端再根据通用的MessageBase,将传过来的二进制流进行反序列化,创建一个对象。这样服务端就知道客户端要发送的客户端地址了。
同时,在MessageHeader中还可以包含源地址,那么,服务端可以根据这些信息,创建一个地址池,再次传送消息时,可以直接从这里获得目标地址。
接下来,再创建两个控制台程序,分别引用客户端组件和服务端组件,分别做为客户端程序和服务端程序。
然后就可以发送和接收消息了。