(注:本文所讲的网络协议只针对TCP协议)
背景:开发一个C/S的应用势必需要服务端和客户端的适配,包括网络协议、数据传输格式、业务处理的适配。由于服务端承载着大量的客户端,需要高并发、高性能、高可靠性,在我们的认知里往往认为服务端的网络模型和架构设计很复杂。但是客户端嘛,无非就是建立网络连接,发个请求收个回复如此简单。所以在工作中经常会出现有些客户端处理界面和业务的同事对平台开发者说,你做好服务端的网络就好,客户端的网络我来处理,而且在他们的想法里,这个所谓的客户端网络库只需要很短的时间就可以做完,每每遇到这种情况,我都会问几个问题劝他们放弃这种想法,由更擅长进行网络编程的平台端来提供网络库,为什么呢?
先看看我常问的几个问题。
问:你打算怎样实现客户端的网络层?
答:对于TCP协议来说无非就是connect,send,recv呗。
问:那你是否考虑到这种情况,你同时或者先后发过去两个网络请求,你怎么确定你收到回复是哪个请求的?
(其实问到这时有些同事就开始不理解了,我会给他们解释网络传输和服务器处理不是串行的,往往会出现你后发的请求却先收到回复,客户端 多线程情况下更为常见。当然也有有办法的。)
答:那我对每一个请求加一个唯一标识,这样我就可以分辨出来了。
问:你有没有考虑过由于connect,send,recv...这些系统API都是阻塞的,如果没有限制条件,会让你的一个请求卡住很长时间或者永远卡住?
问:你有没有考虑过短连接请求,长连接请求,服务端推送消息如何实现?
问:你有没有考虑过各种网络错误和异常的监控和处理,比如TCP长连接网络断开后的自动重连?
问:你有没有考虑过如果你把网络层或者网络数据层和前台业务和界面混杂在一起后的代码混乱复杂度?
问:你对TCP了解多少,仅仅是会用网络编程的API还是知道TCP还拥有一些诸如TIME_WAIT、TCP_NODELAY...的状态或特性,你知道经常说的粘包是怎么回事吗?
往往这些问题问出来一个或者几个之后一些人就会意识到凭他目前对网络编程的把控还不足以写一个生产环境级别的客户端网络库,其实我曾经也有过类似认为客户端网络库实现很sample的native的想法,但是当我配合着服务端用年计的时间逐渐在测试和生产环境中写出和完善出一个客户端网络库后才意识到它真的并不简单。
一切尽在不言中,程序员最好的交流语言就是代码,希望我的语言不至于很晦涩难懂。感兴趣的朋友可以参考我的github上的RPC_Framework这个项目参考一下我的网络库的写法,目前在公司生产环境中我已提供了linux平台、android平台、ios平台、windows平台的版本。github上的工程减少了一些功能,其中windows的版还未完全完成,希望大家能够提出宝贵的意见。