高分求解 关于 idTcpClient 传文件的问题.

时间:2021-06-07 19:54:29
问题描述:
1.客户端用idTcpClient 服务端是IOCP 当客户端用一个链路传输多文件过程中,有的文件只能传一半,有的可以   传完. 当客户端使用多个链路时(一个文件一个链路)时是可以全部传完的.

2.客户端用idTcpClient 服务端是idTcpServer 一个链路传多文件是可以全部完成的.

根据以上原因,帮分析一下这是啥原因..分不够再给..谢谢..

15 个解决方案

#1


协议定义清楚,不要串包就没有问题.

#2


协议没问题的,,虽说是一链路,但是收到包以后会根据包中的标记来分配数据包的.

#3


Send/Write指定的字节数并不一定能够一次调用send就完成发送,从而如果要发送多个文件的话,必须保证第一个"包"(分片)在发送完成之前中间不会插入其它"包"

#4


上面的可能性我分析了一下也不存在,因为是一个链接,所以只有一个线程在接收数据,在收到对方的一个确认后才发第二个包(虽说是用了TCP,但是还是用的确认的这种方式),所以就算是多个文件分一块发,在里面的执行过程其实是排着队发出去的.

#5


好像和我遇到的问题相似,但是又不大一样。
网络传输需要考虑的因素他多了,建议:1、包要自己拆分和组装;2、每个包的大小最好在1350字节以内(网络设备的一个参数限制);

TCP协议是能够自己拆分大包,但是有时候网络环境复杂的话拆分的包可能走不同的网络路由,导致接收
某一个小包的时候超时。。。
可以用tracert 跟踪一下看看路由情况

在发送接收的时候要考虑socket buffer的大小是否修改成合适的大小了

#6


使用TCP就不应该存在丢包的情况,但是要做好异常处理,比如连接断了,需要重传,另外建议楼主最好一个连接传一个文件,这样逻辑处理比较简单,便于维护,如果控制太多,不利于整个系统的稳定。

#7


引用 6 楼 Bear_hx 的回复:
使用TCP就不应该存在丢包的情况,但是要做好异常处理,比如连接断了,需要重传,另外建议楼主最好一个连接传一个文件,这样逻辑处理比较简单,便于维护,如果控制太多,不利于整个系统的稳定。

up

#8


引用 4 楼 myart 的回复:
上面的可能性我分析了一下也不存在,因为是一个链接,所以只有一个线程在接收数据,在收到对方的一个确认后才发第二个包(虽说是用了TCP,但是还是用的确认的这种方式),所以就算是多个文件分一块发,在里面的执行过程其实是排着队发出去的.

是只有一个线程在发吗?还是多个?如果是只有一个线程在发,就不会有类似问题,如果不是,那就不是那么回事。

#9


一个文件一个线程用来处理文件数据的读写,但是TCP只有一个线程来接收,接收到一个确认包后根据包的
标识派到相应的文件线程(数据包传到文件线程时会把SOCKET传进去),文件线程处理好后,进行发送下一包。
在这里面虽说每个文件一个线程,但是TCP只有一个接收线程,而且是接一个包处理一个包。这样分析下去,最终发送时不会存在并发发送。今天在TCP的接收线程中,在处理完一个包以后加了一句sleep(0).加上去以后已经
正常,目前还在观察中..请各位朋友继续分析一下.另外我想把接收缓存再加大一点.目前是用的默认的8K吧.

#10


上面所说的正常是服务器和客户端都在一台机器上是正常的,但是服务端放到其它服务器上测,还会出现以前的问题.郁闷透了..

#11


不清楚你们的IOCP当中是如何处理的,一般来说,IOCP当中对于同一个连接应该只保持一个未决的接收请求,从而保证能够顺序处理。

#12


是的,总会有一个接收请求在队列里面的. 所以说在多个文件同时传时,有的文件能顺利传完,有的只能传一半.

#13


引用 12 楼 myart 的回复:
是的,总会有一个接收请求在队列里面的. 所以说在多个文件同时传时,有的文件能顺利传完,有的只能传一半.

如果能够保证同一时间仅有一个Recv请求,就不会存在这个问题。当然在处理的时候一定要有一个先后顺序,同一个连接当中,当A线程收到数据并处理的时候,应该在该连接上加锁,从而保证后续收到的数据能够依序进行处理,而不会因为某种原因,A线程的处理还没有完成,B线程的处理却依先完成,导致乱序。

#14


嗯..谢谢僵哥一直对这个问题的关注,,不过A线程和B线程到开始接收文件时是顺序执行的(虽说是线程,但是到后面开始接收文件时,线程已挂起了,是TCP接收线程调用他们的函数进行文件写操作的),,所以不会存在A没处理完,B已处理完的情况发生.

#15


哎..原因终于找到了,原来是IOCP服务器接收到的数据产生了粘包现像,我而接收一次只做为一个包处理, 
这样接收缓存中的数据后一半会没处理...真是郁闷啊..查了这么久..不过最终还是解决了,目前正在观察中.

再次感谢各位朋友的支持.
散分...

#1


协议定义清楚,不要串包就没有问题.

#2


协议没问题的,,虽说是一链路,但是收到包以后会根据包中的标记来分配数据包的.

#3


Send/Write指定的字节数并不一定能够一次调用send就完成发送,从而如果要发送多个文件的话,必须保证第一个"包"(分片)在发送完成之前中间不会插入其它"包"

#4


上面的可能性我分析了一下也不存在,因为是一个链接,所以只有一个线程在接收数据,在收到对方的一个确认后才发第二个包(虽说是用了TCP,但是还是用的确认的这种方式),所以就算是多个文件分一块发,在里面的执行过程其实是排着队发出去的.

#5


好像和我遇到的问题相似,但是又不大一样。
网络传输需要考虑的因素他多了,建议:1、包要自己拆分和组装;2、每个包的大小最好在1350字节以内(网络设备的一个参数限制);

TCP协议是能够自己拆分大包,但是有时候网络环境复杂的话拆分的包可能走不同的网络路由,导致接收
某一个小包的时候超时。。。
可以用tracert 跟踪一下看看路由情况

在发送接收的时候要考虑socket buffer的大小是否修改成合适的大小了

#6


使用TCP就不应该存在丢包的情况,但是要做好异常处理,比如连接断了,需要重传,另外建议楼主最好一个连接传一个文件,这样逻辑处理比较简单,便于维护,如果控制太多,不利于整个系统的稳定。

#7


引用 6 楼 Bear_hx 的回复:
使用TCP就不应该存在丢包的情况,但是要做好异常处理,比如连接断了,需要重传,另外建议楼主最好一个连接传一个文件,这样逻辑处理比较简单,便于维护,如果控制太多,不利于整个系统的稳定。

up

#8


引用 4 楼 myart 的回复:
上面的可能性我分析了一下也不存在,因为是一个链接,所以只有一个线程在接收数据,在收到对方的一个确认后才发第二个包(虽说是用了TCP,但是还是用的确认的这种方式),所以就算是多个文件分一块发,在里面的执行过程其实是排着队发出去的.

是只有一个线程在发吗?还是多个?如果是只有一个线程在发,就不会有类似问题,如果不是,那就不是那么回事。

#9


一个文件一个线程用来处理文件数据的读写,但是TCP只有一个线程来接收,接收到一个确认包后根据包的
标识派到相应的文件线程(数据包传到文件线程时会把SOCKET传进去),文件线程处理好后,进行发送下一包。
在这里面虽说每个文件一个线程,但是TCP只有一个接收线程,而且是接一个包处理一个包。这样分析下去,最终发送时不会存在并发发送。今天在TCP的接收线程中,在处理完一个包以后加了一句sleep(0).加上去以后已经
正常,目前还在观察中..请各位朋友继续分析一下.另外我想把接收缓存再加大一点.目前是用的默认的8K吧.

#10


上面所说的正常是服务器和客户端都在一台机器上是正常的,但是服务端放到其它服务器上测,还会出现以前的问题.郁闷透了..

#11


不清楚你们的IOCP当中是如何处理的,一般来说,IOCP当中对于同一个连接应该只保持一个未决的接收请求,从而保证能够顺序处理。

#12


是的,总会有一个接收请求在队列里面的. 所以说在多个文件同时传时,有的文件能顺利传完,有的只能传一半.

#13


引用 12 楼 myart 的回复:
是的,总会有一个接收请求在队列里面的. 所以说在多个文件同时传时,有的文件能顺利传完,有的只能传一半.

如果能够保证同一时间仅有一个Recv请求,就不会存在这个问题。当然在处理的时候一定要有一个先后顺序,同一个连接当中,当A线程收到数据并处理的时候,应该在该连接上加锁,从而保证后续收到的数据能够依序进行处理,而不会因为某种原因,A线程的处理还没有完成,B线程的处理却依先完成,导致乱序。

#14


嗯..谢谢僵哥一直对这个问题的关注,,不过A线程和B线程到开始接收文件时是顺序执行的(虽说是线程,但是到后面开始接收文件时,线程已挂起了,是TCP接收线程调用他们的函数进行文件写操作的),,所以不会存在A没处理完,B已处理完的情况发生.

#15


哎..原因终于找到了,原来是IOCP服务器接收到的数据产生了粘包现像,我而接收一次只做为一个包处理, 
这样接收缓存中的数据后一半会没处理...真是郁闷啊..查了这么久..不过最终还是解决了,目前正在观察中.

再次感谢各位朋友的支持.
散分...