初探基于TCP的服务器/客户端结构的聊天系统

来源:互联网 发布:mvc4后台开发框架源码 编辑:程序博客网 时间:2024/06/05 01:52

    一个多月前读完了Stevens的《Unix网络编程》,想稍微实战一下,把学到的东西巩固巩固。于是就选择了做一个类似于QQ这样的程序。

    刚开始想的比较简单,因为自己写一些简单的通信程序也写的不少了,以为会很顺利,一个多月做下来,发现满不是那么回事。

    首先是通信协议的选择。现有的大部分IM(Instant Messenger,简称IM)程序都是基于UDP的,我也觉得UDP的很方便,因为可以只用一个套接字就可以处理所有的通信任务。但是我稍微我往下深入思考一步,就发现了一个很大的问题:注册登录过程怎么样保证用户信息的安全?关于这个问题,我也尝试去了解腾讯的解决方案,结果是,腾讯是在应用层实现了自己的安全。仅仅一个登录过程,就需要5次往返的传递包才最终确定一个会话的密钥,从而使用这个密钥进行对称加密通信。我自己对密码学的东西不甚了解,我总不能为了实现一个相对安全的登录就自己实现一个加密算法吧?所以只好考虑其他的方法了。现有的比较成熟的加密通信(限于我自己查资料所能了解的)的方式有IPSec和SSL,IPSec是基于IP层之上的安全,而SSL是传输层之上的安全。当时应该是对这两种方法做了比较,IPSec应该是需要比较多的配置,编程方面不是很方便,并且也不利于用户使用,所以最后选定了用SSL来保证数据传输的安全性。但是对安全稍有了解的同学都知道,SSL只能保证通信过程的安全,却不能保证通信对端身份的安全。对身份的认证应该加入数字证书。我做的东西只是一个学习性的,所以就只是使用了一个自己生成的数字证书安装到服务器上,商用的应该是要有第三方认证的数字证书才可以,这样就可以实现对服务器身份的认证。至于对客户端身份的认证主要就靠帐号和密码来实现了。扯了这么多,其实最开始的问题是:到底是使用UDP还是TCP?无论是机缘巧合还是其他各种原因,我最终还是决定使用TCP。首先,TCP是可靠的,这样就不需要自己在应用层上实现可靠性。其次,SSL也应当建立在TCP之上。最后,因为Stevens书中的大多数例子和服务器都是基于TCP的,UDP的服务器太过于乏味了,所以我还是要不走寻常路一回,使用TCP搭建服务器。

    通信协议选定以后,接下来的就是服务器范式的选择了。既然做就要做好,这是我的理念。当然,我还没这实力。《Unix网络编程》这本书中给出了9个范式,我选择了第8个范式:预先创建线程服务器,使用互斥锁保护accept。原因很简单,因为这个范式是这9个范式中性能最好的。有兴趣的同学可以参看书中30章的内容。我这个服务器主框架基本没怎么改就用上了。当然,也可以做的更好一些就是根据实际负载情况动态创建线程个数。

    再接下来就是数据库的选择了。我用的是MySql。这个就没什么具体的原因了。数据库和服务器的具体实现是由我的搭档做的。我就不做过多的解释了。

    通信方式选定了,还要确定通信过程。既然是TCP的,就必须要处理TCP本身固有的一些问题。TCP是面向连接的,那么是不是应该每一个登录用户都要与服务器时刻保持连接呢?我们先做这样的假设:每个客户都保持与服务器的连接,然后通过这个连接与服务器进行通信从而获取服务。那么服务器的性能就会遭遇两个瓶颈:服务器的并发线程数的限制和通信可用端口数的限制。因为服务器需要为每个客户创建一个线程去监听用户的服务请求,并且这些线程大部分时间都只是处于休眠状态(准确的说是在等用户发送服务请求),但是我们知道,每个线程都是需要一定的开销的。还有一个问题就是端口数量的限制,系统只有65535个可用TCP端口,除去知名端口和一些已用端口,剩余的端口数也就是6万多个(《Unix网络编程》这本书中是这样划分的:0~1023是众所周知的端口;1024~49151是已登记的端口,由IANA控制;49152~65535是动态的或者说私用的端口。如果已登记端口不能使用的话那就只有1W多个可用端口了),这大大限制了服务器并发服务用户数量。所以这种方法是行不通的。Web服务器的工作模式是这样的:客户端(也就是Web浏览器)连接服务器并向服务器发送网页请求,服务器收到连接请求后返回网页并向断开连接。这种工作方式非常适合客户端与服务器通信并不密集的情况,IM程序即属于这种情况。所以我们就需要采用这种工作模式。客户端需要向服务器发送消息的时候,首先与服务器建立连接,服务器收到连接申请之后进行三次握手建立连接。服务器处理请求消息,完成后关闭连接。

    整体框架就是如此。写了这么多感觉看着好乏味。其实真正做的过程中也是这样的,前期花了大量的时间去设计一些能思考的问题的解决方案的细节,即使是这样,在编写过程还是会遇到前面未曾想到的问题。先写这么多吧,后续的更细节的东西会慢慢的更新出来。

原创粉丝点击