Web版PACS开发纪要二:解决文件传输数据“丢失”问题

在Web版PACS开发中,利用socket传输DCM文件时遇到数据丢失问题。经过分析,发现是由于接收端recv函数未正确处理接收字节导致。解决方案包括对recv返回值进行判别,确保正确处理基本信息和文件数据,以及通过同步send和recv来避免数据错乱。
摘要由CSDN通过智能技术生成

Web版PACS开发纪要二:DCM文件的网络传输

——解决文件传输数据“丢失”问题

目录

背景介绍

问题搜索

问题分析

问题解决


0背景介绍

该工程是上个月博文的延续。在利用“完成端口”完成了文件自动归档的基础上,本次需要利用socket套接字进行文件的远距离传输。虽然socket编程的参考书籍很多,但是在具体实现过程中还是遇到了各种各样的问题。下面继续记录一下工作中遇到的问题,一方面作为工作纪要,为后续工程的扩展做准备,另一方面作为自己学习的笔记,加深网络编程方面的知识。

首先说一下socket套接字传输文件部分的基本流程:首先利用上次完成的“文件夹实时监控”,将文件从分散的文件夹中归档到统一的目录下,默认为:e:\MedicalImages;然后利用socket套接字结合完成端口,将e:\MedicalImages文件夹下的文件传输到远端服务器。基本结构图如下:


1问题搜索


从图中可以看出,原始字节流(即源文件)比目标字节流(接收到的文件)多出了850字节。但是在调试过程中并未发现有send或recv函数发出错误,那么这“丢失”的850字节去哪里了呢?对此问题进行搜索

尝试一:send和recv函数是否是阻塞的?

send

客户端和服务端都通过send函数来向TCP连接的另一端发送数据

客户端用send向服务端发送请求;

服务端用send向客户端发送应答
recv 客户端和服务端都通过recv函数接收来自TCP连接另一端的数据

1.1简言之,阻塞就是send和recv必须完成其相应的任务才返回,将控制权交给自己编写的程序;非阻塞就是send和recv未等其任务完成就直接返回,将控制权交给调用者程序;

1.2阻塞时刻

send和recv函数的阻塞与accept函数的阻塞时刻略有不同,这是由于函数实现的功能以及TCP协议造成的。send函数的工作是将给定缓冲区(此缓冲区是程序中由程序员自己开辟的,存在于程序的堆或栈中)中的数据拷贝到TCP/IP协议栈的缓冲区(传输层开辟的接收/发送缓冲区,不同于程序员自己开辟的堆栈空间),在协议栈缓冲区未满时,阻塞和非阻塞的send函数效果相同都会直接返回,代表数据发送成功,其实此时数据依然存在于send端的TCP/IP协议栈的缓冲区中,并未真正发送出去;当协议栈缓冲区已满,阻塞和非阻塞的send函数就表现出了不同,阻塞send函数会将调用进程(线程)挂起,直到协议栈缓冲区中有足够的空间来存储send函数中指定的程序缓冲区数据,有时为了防止程序阻死会设置超时时间,当超过此时间阻塞send函数也会返回。非阻塞send函数发现协议栈缓冲区没有足够空间时,尽能力的拷贝,返回成功拷贝的大小;如缓存区可用空间为0,会立刻返回,并提示WSAEWOULDDBLOCK给程序员,告知“协议栈缓冲区已满,数据无法拷贝”——你自己想办法处理吧o(╯□╰)o”

【小结】:单步调试分项目,发现send和recv函数并未出现阻塞现象,也就是说在传送过程中TCP/IP协议栈的缓冲区空间充裕。那么为何会“丢失”数据呢?

参考博文:

http://blog.csdn.net/xiaofei0859/article/details/6037814    (Windows下情形)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zssure

己欲立而立人,己欲达而达人

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值