Unix网络编程-UDP客户端服务器示例(2)

一个简单的UDP客户端/服务器程序示例,这个简单的例子执行如下步骤的一个回射服务器:

1) 客户端从标准输入读入一行文本,并写给服务端

2) 服务端从网络输入读入一行文本,并回射给客户端

3) 客户端从网络输入读入这行回射的文件,并显示在标准输出上。

下图描述了这个简单的客户/服务器:

UDP回射服务器程序和UDP回射客户端程序见上篇,略

数据报的丢失

我们的UDP客户/服务器例子是不可靠的。如果一个客户数据报丢失(譬如说,被客户主机与服务器主机之间的某个路由器丢弃),客户端将永远阻塞于dg_cli函数中的recvfrom调用,等待一个永远不会到达的服务器应答。类似的,如果客户数据报到达服务器,但是服务器的应答丢失了,客户端也将永远阻塞于recvfrom调用。防止这样永远阻塞的一般方法是给客户的recvfrom调用设置一个超时。

仅仅给recvfrom调用设置超时并不是完整的解决办法。举例来说,如果确实超时了,我们将无从判定超时的原因是我们的数据报没有到达服务器,还是服务器的应答没有回到客户。如果客户的请求是“从账户A往账户B转一定数目的钱”而不是我们的简单回射服务器例子,那么请求丢失和应带丢失是极不相同的。因此需要给UDP增加可靠性

验证接收的响应

知道客户临时端口号的任何进程都可以给客户发送数据报,而且这些数据报会与正常的服务器应答混杂。可以recvform调用以返回数据报发送者的IP地址和端口号,保留来自服务器的应答,忽略任何其他的数据报。

如下所示:

如果服务器是运行在一个只有单个IP地址的主机上,那么这个新版的客户端能正常工作。然后如果客户端是多宿的,客户端就有可能失败。因为recvfrom返回的IP地址,可能不是我们发送指定的IP地址,服务器可能选择从其他的IP作为外出接口。

一个解决办法是:得到recvfrom返回的IP地址后,客户端通过在DNS中查找服务器主机的名字来验证该主机的域名而不是IP地址。另一个解决办法是:服务端为每个IP地址创建一个套接字,用bind捆绑各自的IP到各自的套接字。这样,就会从对应的IP地址上响应客户端。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容