漫谈网络编程中的容错处理

来源:互联网 发布:淘宝的降价通知 编辑:程序博客网 时间:2024/06/16 12:41

 当我们编写服务器程序时,肯定离不开网络编程。网络编程通俗一点讲,就是接受来自客户端的请求消息,处理并返回相应的回复给客户端。大都时候,我们在传输消息时,都选择了TCP协议。TCP协议提供了可靠的传输,不需要编程人员考虑消息是否送达对方。但是我们往往忽略了可能存在的问题。考虑如下的一个例子

    假设有一台缓存服务器,保存了一些简单的键值对。客户端可以连接到服务器,设置键值,或者查询一个键。
客户端要设置一个字符串类型的变量名假设为msg,它的值为"hello world",那么发送给服务器的消息为"set msg hello world"。关键代码如下:

char buf[100] = "set msg hello world";int fd;//fd为客户端与服务器连接的套接字send(fd,buf,strlen(buf));

如果这样写,我们根本不知道消息有没有完整的发送到服务器。send()函数不能保证一次将所有字符都发送出去,在网络拥堵的情况下,丢失消息是很正常的。所以必须要判断send函数的返回值。

char buf[100] = "set msg hello world";int fd;//fd为客户端与服务器连接的套接字int len = 0;while(len != strlen(buf)){    len+= send(fd,buf+len,strlen(buf)-len);}

而在服务端,也可以很简单的写出读取的代码

char buf[100] =0;int fd;read(fd,buf,sizeof(buf));parse(buf);//对消息进行处理


这里的read会存在同样的问题。假设客户端发来的消息由于网络问题,第一次只接受到一半。得到了一个不完整的消息,服务器没办法解析,直接丢弃么?显然这不是我们想要的结果。当然我们也可以继续等待未接受的另一半消息,但是问题是这条消息到底有多大我们并不知道。或者存在消息混杂的情况,比如客户端发送了两条消息A和B给服务器,而服务器接受到的内容为

第一条:A/2

第二条:A/2,B/3

第三条:B2/3

如果服务器读出了这样的消息我们能正确处理吗?每一条消息都不是完整的,我们如何从这分离的消息中得到完整的一条消息呢。那么这里就需要依赖消息协议的定义了。

我们需要规定一条消息的开始与结束标志。

比如当我们接受到第一条信息时,只检测到了A消息的开始标志,并没有结束标志。那么现将第一条消息保存到缓冲区中,并可以解析出已经读取到的内容。第二条消息来的时候,我们检测到了A的结束标志,那么就可以构成一条完整的消息。这时,我们就可以处理消息A了,并且将处理结果返回给客户端。然后销毁之前保留在缓冲区的内容。接着处理剩下的B消息。按照这样的方式,我们就可以解决因网络问题而接受到不完整的信息了

0 0