求:大文件传输程序(比方说传电影)

时间:2021-06-05 12:30:47
自己写了一个,但是传小文件没问题,传大文件就出错,传电影传了50M就报错,或者几M就报错,
谁有写过大文件传输的程序帮忙给个,或者把技术难点及解决方法说下也可以。谢谢。

50 个解决方案

#1


你是怎么做的?

#2


参考
http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx

#3


引用 1 楼 glorywu 的回复:
你是怎么做的?


你可以看我另一个帖子,附上代码了,不过还没解决问题
http://topic.****.net/u/20091022/15/932432b6-af40-45e4-845c-9de2c60355ad.html

#4


关注。。。

#5


试试连续两次发送时,中间加个Sleep(2毫秒)(或再增大)延时;

#6


引用 5 楼 dijkstar 的回复:
试试连续两次发送时,中间加个Sleep(2毫秒)(或再增大)延时;


加了Sleep(1000)没用

#7


把完整的程序贴出来吧,帮你调!

#8


如果是UDP,应该给每个包编号,接收端按编号组装。
如果是TCP,应该不会有这个问题~~

#9


http://topic.****.net/u/20091022/15/932432b6-af40-45e4-845c-9de2c60355ad.html
这里有主要的代码

是tcp的  现在也在看这方面的资料。调试的话不好调的啊,都是发送了一段时间出的问题。
不可能断点跟踪的啊

#10


断点续传吧

#11


贴点关键代码吧。主要如下
1.不知道你是同步还是异步的发,发送的返回值判断的有没有问题。
2.不知道你的传输协议组装和解析有没有问题。

#12


接受文件的那端一直recv,直到接收到的字节数和你所发送的文件大小相同。

#13


这个肯定要用断点续传的方法,具体做法就是将文件按固定大小切成极端,每一段传送时要传送该段在文件中的起点,最后一段不足固定长度补充自己可识别的数据就行了。这样接收到数据后只要按照每一段的起点位置连接起来就可以了。

#14


引用 2 楼 fishion 的回复:
参考
http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx


看了上面的演示代码,和我的区别就是发送和接收的时候设了保护,根据函数返回值
做了判断,我想问题也应该是出在这里,毕竟按1000字节一次次的传,传大文件是要
传几十万次的,socket函数出问题的概率也大了,不过就算少传了或少读了怎么程序
出错呢?应该是最后接收的文件有问题吧!  谁能解释下? 解释出来的就结贴给分了。

#15


学习,期待高人!

#16


可不可能出现这种情况:
struct A
{
    int a;
     BYTE buf[1000];
}

A  a[3];

当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分
到达了。  会出现这种情况吗??(每次都是发送一个A结构)

#17


引用 16 楼 yaozhiyong110 的回复:
可不可能出现这种情况:
struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分
到达了。  会出现这种情况吗??(每次都是发送一个A结构)
这种同样大小的数据传送是否出现后发先至没试过,但确有不同大小时,当前一部分大而后一部分小时常出现后发先到的情况。另外,对于这种情况你接收应该先按收到的int a排列存起来,等全部收齐或收到连续的NO时再连接文件吧。

#18


TCP 会粘包的, 接收一次的数据大小并不是发送方一次的数据大小

#19


void CFileRDlg::SendData(CMysock *sock)
{
int sendcount = 0;
int count = SIZE_CFileData;  // 结构体的大小,即一个包的长度
do 
{
sendcount = sock->SendMsg(&m_Data + sendcount,count);
count -= sendcount;
} while(count > 0);
}

void CFileRDlg::ReceiveData(CMysock *sock)
{
int Recount = 0;
int count = SIZE_CFileData;  // 结构体的大小,即一个包的长度
do 
{
Recount = sock->ReceiveMsg(&m_Data + Recount,count);
count -= Recount;
} while(count > 0);
}

m_Data 是类成员。一个如下的结构体
struct CFileData
{
int Msg;
int count;
BYTE buf[1000];
};

这是我修改以后接收和发送的函数,考虑了一次没发完或没接完的情况。这样如果没发完或
没接收完整都会继续发剩下的或接收剩下的。
不过就像我前面说的 :当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分 到达了。   这种情况下还是会乱。

还有个疑问就是,发多少我接多少。程序为什么会出错呢? 顶多是接收完的文件乱了,程序为什么运行部下去?

#20


有没有谁清楚:

struct A 

    int a; 
    BYTE buf[1000]; 


A  a[3]; 

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分   这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

#21


这个好办,发送方转a[1],接收方一定要收满a[1]才接收a[2],TCP是有序的

#22


发送端速度过快,造成堵塞,发送缓冲区满之后就会丢数据,然后就造成数据不准确了。
解决方法一、设置发送缓冲区成更大的值(不提倡)。
解决方法二、使用确认包,每次只发一个小包,客户端收到后向服务端发“确认”反馈,服务端等收到“完成”后再发下一个包。
解决方法三、采用完成端口技术……

#23


谁把我的问题解释下好吗?

可不可能 a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢? 
这很重要啊 

也就是说我发一个包出去,会不会接收的时候一个包变好几个了

#24


解决方法三、采用完成端口技术……  ?  什么东西??

#25


注意缓冲区

#26


引用 20 楼 yaozhiyong110 的回复:
有没有谁清楚:

struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

TCP不会给你乱序的,也不会给你给你中间发丢的,发文件建议使用TCP,用UDP你还是一样要做应答,因为文件是一个字节也不允许丢和乱的,而TCP都做好了这层,自己也就没必要重复工作了

#27


引用 26 楼 spirit008 的回复:
引用 20 楼 yaozhiyong110 的回复:
有没有谁清楚:

struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

TCP不会给你乱序的,也不会给你给你中间发丢的,发文件建议使用TCP,用UDP你还是一样要做应答,因为文件是一个字节也不允许丢和乱的,而TCP都做好了这层,自己也就没必要重复工作了


就是说 我发a[1] a[2] a[3] 那么只有可能顺序乱了 不可能出现包被分解是吧(a[1] a[2] a[3]肯定是一个整体) 是这意思吗?

#28


顺序都不会乱??

#29


估计你用的是socket函数写的
socket在传输的时候有的结构体可能接受的不完整,
要自己检查介绍到的字节数和结构体的size比较.
你可以用CSocket类来实现,可能不用关心这些细节.

#30


http://download.****.net/source/1777622

#31


我是用CSocket写的啊  CMysock继承的CSocket 自己稍微封装了下而已  这两天自己在写,现在可以传了

我现在只想知道 :
TCP 我发a[1] a[2] a[3]  接收端的情况可能是怎样?(不会乱序?,不会分包?)

UDP呢? 知道的说下好不?(这问题解决就结贴给分了)

#32


用tcp发送a[1],a[2],a[3]接受端不会乱序
但是,如果你的a[1]大小是1024,接受到的大小就有可能小于1024然后你需要再接受剩下的字节数.

#33


引用 32 楼 zhyhchg 的回复:
用tcp发送a[1],a[2],a[3]接受端不会乱序
但是,如果你的a[1]大小是1024,接受到的大小就有可能小于1024然后你需要再接受剩下的字节数.


我发a[1]a[2]a[3]
也就是说TCP发过来的肯定是 a[1]a[2]a[3]这样的顺序对吧
不会是a[1]a[3]a[2] 或者a[1] a[2]一部分 a[3] a[2]另一部分 这种情况吧。

UDP呢? 情况会很复杂?

#34


没处理沾包或未按顺序处理包!

#35


TCP是顺序是不会乱的,不过如果是没封装的Socket程序仍然需要处理分包,IP分片的大小如果大于1500就不能发送了。所以你的数据包应该控制到这个范围内,如果是支持外网特别是UDP发送的情况应该控制到1000左右,这个只是我个人测试时的经验数据。UDP发送时接收端收到的顺序可能会出现错误也就是你说的1 3 2的顺序,需要缓存以及给每个包编号然后还原数据顺序来处理。另外还可能出现丢包现象,如果是传送文件还需要你自己处理重发机制等等

#36


引用 24 楼 yaozhiyong110 的回复:
解决方法三、采用完成端口技术……  ?  什么东西??

完成端口就是重叠异步IO完成端口的简称,也就是IOCP,他只是一种通信模型,和select  WSAAnyncSelect  event等等是平级的,你可以先不管这个
发文件你可以选UPD和TCP都可以,UPD要麻烦得多,因为UPD可以丢包的,所以你得做校验,而且你第一次发的,他不一定是第一次收到的,也不一定能收全,但他的速度是最快的.TCP就简单多了,只要建一条连接,然后在服务端顺序读文件,并发给客户端,然后客户端顺序写文件就行了,不用做校验,也不用但心先发的后到,数据没收完等问题,但速度慢一点.如果你在局域网,或者在网络比较好的时候,你感觉不到的.

#37


建个议哈,如果初学,用TCP吧

#38


引用 35 楼 eyodo8 的回复:
TCP是顺序是不会乱的,不过如果是没封装的Socket程序仍然需要处理分包,IP分片的大小如果大于1500就不能发送了。所以你的数据包应该控制到这个范围内,如果是支持外网特别是UDP发送的情况应该控制到1000左右,这个只是我个人测试时的经验数据。UDP发送时接收端收到的顺序可能会出现错误也就是你说的1 3 2的顺序,需要缓存以及给每个包编号然后还原数据顺序来处理。另外还可能出现丢包现象,如果是传¡­


我嫌1024小啊 我都是 1024 * 16 一个包啊  会分包?
不过现在我的程序 顺序发 顺序接都没有问题哦 不过是在自己机子上 没有和别人机子测试

确定包大的话就会分包?

#39


我是用CSocket类的  算是封装了Socket的吧 应该不会分包了吧

#40


UDP 会不会出现 a[1] a[2]一部分 a[3] a[2]另一部分 这种情况?

#41


面向流的TCP才会出现你说的那种情况,UDP是面向包的。我没遇到过你说的那种情况,要么就是收不到。你用CSocket使用TCP时ms使用的Nagle算法可能会出现你说的那种情况。

#42


引用 41 楼 eyodo8 的回复:
面向流的TCP才会出现你说的那种情况,UDP是面向包的。我没遇到过你说的那种情况,要么就是收不到。你用CSocket使用TCP时ms使用的Nagle算法可能会出现你说的那种情况。


你说的我不懂

#43


说白了就是这个意思,做网络编程最好别用MFC的类,那东东不好用,初学最好用TCP,1次最好发1000字节左右,一般做网络编程得自己定义协议的,每一次发的数据是啥,第几次,校验码是啥是数据还是文件头信息,等等,也描术清楚,明白吗,如果不明白,加我QQ:372898309,来我们一起学习,怎么样 

#44


引用 31 楼 yaozhiyong110 的回复:
我是用CSocket写的啊  CMysock继承的CSocket 自己稍微封装了下而已  这两天自己在写,现在可以传了

 我现在只想知道 :
 TCP 我发a[1] a[2] a[3]  接收端的情况可能是怎样?(不会乱序?,不会分包?)

 UDP呢? 知道的说下好不?(这问题解决就结贴给分了)

你采用TCP的话,接收端是一般是不会出现乱序现象(除非发送缓冲区满了,发送数据被丢弃),只可能出现a[1]的一部分,a[1]的第二部分,.....a[1]的第n部分,a[1]的第n+1部分和a[2]的一部分,........,因此最好自己定义一个简单的通信协议,就是在每次发送时加入一个自定义的报头,接收时根据报头来接收。

#45


必须定义好接收方和发送方的协议格式,
还有就是必须处理粘包的问题。

#46


好了,也算有些体会了,谢谢大家帮忙,分就给登级低的吧,反正主要是交流,分又不重要的。
结贴喽。。。。

#47


LZ好象是初学者的,TCP和UDP还没有分清楚呢,最好先搞清楚这个再说。打个比方说吧,在应用层看来,TCP就象双方连立了一个通道,一端的东西流向另一端,可以当成是有序无差错的,但也是*的,没有包的概念,只是字节流,你要自己处理解析。而UDP就象有一个人不停地把东西打成包丢给你,你有可能能接收到,也有可能接收不到,也有可能他先丢的包你后接到,先丢的你先接到。但有一个好处,就是除非你不接到,如果你接到就是一整个包。

TCP的优点是稳定性好,缺点是占资源比较多;UDP的优点时速度快,缺点时稳定性差。具体那一个协议好?没有绝对的标准,只有哪一个更适应你的应用场景。象网络的语音和视频等,丢失一点数据不算什么大不了的事,所以一般采用UDP。对于交易数据或其它重要数据,当然就用TCP了。关于传文件这事,就不太好说了,基本上是功底不太好的就用TCP,毕竟比较简单,如果功底很好又愿意花时间的,就采用UDP了,因为如果处理得应的话,性能可以比TCP高一些。而且在某些应用环境里,只有UDP才能行得通。

回到你说的问题,你是以包为单位发的,看起来象是用UDP。但很明显,你没有对其做额外处理,这样传文件基本上是不可能成功(除非文件足够小,网络条件足够好)。当然这只是猜测了,说不定你是用TCP。如果是用TCP还有这个问题的话,那就是我前几天说的,发送太快造成发送缓冲区满。

#48


强调一下,“就是除非你不接到,如果你接到就是一整个包。”这句没有错,但就算你接到整个包也并不能保证包里的内容是正确的,你还需要进行一定的效验。其实,真实网络上传送的东西,都不能保证是对的,所以理论上都要自己进行效验。

#49


还有包的长度问题,一般情况过1400字节是可以的,但在某些情况下有可能通不过,我以前做的系统就出现过这个问题,但设置成1200就没有遇到过问题了。就算香港、*和大陆之间都没有问题。

#50


该回复于2010-11-26 15:25:40被版主删除

#1


你是怎么做的?

#2


参考
http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx

#3


引用 1 楼 glorywu 的回复:
你是怎么做的?


你可以看我另一个帖子,附上代码了,不过还没解决问题
http://topic.****.net/u/20091022/15/932432b6-af40-45e4-845c-9de2c60355ad.html

#4


关注。。。

#5


试试连续两次发送时,中间加个Sleep(2毫秒)(或再增大)延时;

#6


引用 5 楼 dijkstar 的回复:
试试连续两次发送时,中间加个Sleep(2毫秒)(或再增大)延时;


加了Sleep(1000)没用

#7


把完整的程序贴出来吧,帮你调!

#8


如果是UDP,应该给每个包编号,接收端按编号组装。
如果是TCP,应该不会有这个问题~~

#9


http://topic.****.net/u/20091022/15/932432b6-af40-45e4-845c-9de2c60355ad.html
这里有主要的代码

是tcp的  现在也在看这方面的资料。调试的话不好调的啊,都是发送了一段时间出的问题。
不可能断点跟踪的啊

#10


断点续传吧

#11


贴点关键代码吧。主要如下
1.不知道你是同步还是异步的发,发送的返回值判断的有没有问题。
2.不知道你的传输协议组装和解析有没有问题。

#12


接受文件的那端一直recv,直到接收到的字节数和你所发送的文件大小相同。

#13


这个肯定要用断点续传的方法,具体做法就是将文件按固定大小切成极端,每一段传送时要传送该段在文件中的起点,最后一段不足固定长度补充自己可识别的数据就行了。这样接收到数据后只要按照每一段的起点位置连接起来就可以了。

#14


引用 2 楼 fishion 的回复:
参考
http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx


看了上面的演示代码,和我的区别就是发送和接收的时候设了保护,根据函数返回值
做了判断,我想问题也应该是出在这里,毕竟按1000字节一次次的传,传大文件是要
传几十万次的,socket函数出问题的概率也大了,不过就算少传了或少读了怎么程序
出错呢?应该是最后接收的文件有问题吧!  谁能解释下? 解释出来的就结贴给分了。

#15


学习,期待高人!

#16


可不可能出现这种情况:
struct A
{
    int a;
     BYTE buf[1000];
}

A  a[3];

当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分
到达了。  会出现这种情况吗??(每次都是发送一个A结构)

#17


引用 16 楼 yaozhiyong110 的回复:
可不可能出现这种情况:
struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分
到达了。  会出现这种情况吗??(每次都是发送一个A结构)
这种同样大小的数据传送是否出现后发先至没试过,但确有不同大小时,当前一部分大而后一部分小时常出现后发先到的情况。另外,对于这种情况你接收应该先按收到的int a排列存起来,等全部收齐或收到连续的NO时再连接文件吧。

#18


TCP 会粘包的, 接收一次的数据大小并不是发送方一次的数据大小

#19


void CFileRDlg::SendData(CMysock *sock)
{
int sendcount = 0;
int count = SIZE_CFileData;  // 结构体的大小,即一个包的长度
do 
{
sendcount = sock->SendMsg(&m_Data + sendcount,count);
count -= sendcount;
} while(count > 0);
}

void CFileRDlg::ReceiveData(CMysock *sock)
{
int Recount = 0;
int count = SIZE_CFileData;  // 结构体的大小,即一个包的长度
do 
{
Recount = sock->ReceiveMsg(&m_Data + Recount,count);
count -= Recount;
} while(count > 0);
}

m_Data 是类成员。一个如下的结构体
struct CFileData
{
int Msg;
int count;
BYTE buf[1000];
};

这是我修改以后接收和发送的函数,考虑了一次没发完或没接完的情况。这样如果没发完或
没接收完整都会继续发剩下的或接收剩下的。
不过就像我前面说的 :当我传送数据的时候,a[1]到达了  a[2]的前一部分到达了  a[3]到达了, a[2]的后一部分 到达了。   这种情况下还是会乱。

还有个疑问就是,发多少我接多少。程序为什么会出错呢? 顶多是接收完的文件乱了,程序为什么运行部下去?

#20


有没有谁清楚:

struct A 

    int a; 
    BYTE buf[1000]; 


A  a[3]; 

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分   这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

#21


这个好办,发送方转a[1],接收方一定要收满a[1]才接收a[2],TCP是有序的

#22


发送端速度过快,造成堵塞,发送缓冲区满之后就会丢数据,然后就造成数据不准确了。
解决方法一、设置发送缓冲区成更大的值(不提倡)。
解决方法二、使用确认包,每次只发一个小包,客户端收到后向服务端发“确认”反馈,服务端等收到“完成”后再发下一个包。
解决方法三、采用完成端口技术……

#23


谁把我的问题解释下好吗?

可不可能 a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢? 
这很重要啊 

也就是说我发一个包出去,会不会接收的时候一个包变好几个了

#24


解决方法三、采用完成端口技术……  ?  什么东西??

#25


注意缓冲区

#26


引用 20 楼 yaozhiyong110 的回复:
有没有谁清楚:

struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

TCP不会给你乱序的,也不会给你给你中间发丢的,发文件建议使用TCP,用UDP你还是一样要做应答,因为文件是一个字节也不允许丢和乱的,而TCP都做好了这层,自己也就没必要重复工作了

#27


引用 26 楼 spirit008 的回复:
引用 20 楼 yaozhiyong110 的回复:
有没有谁清楚:

struct A
{
    int a;
    BYTE buf[1000];
}

A  a[3];

我按a[1] a[2] a[3] 发送数据,数据可能会a[1] a[3] a[2]到达 这我能理解。但是可不可能
a[1] a[2]的一部分 a[3] a[2]的剩下一部分  这种情况呢?

如果是这样那就很不好办了啊,数据包乱了不要紧,比方说上面的,我可以用a来判断顺序,但如果
传输的时候一个包被分解了,那就不能根据a来判断了啊!

TCP不会给你乱序的,也不会给你给你中间发丢的,发文件建议使用TCP,用UDP你还是一样要做应答,因为文件是一个字节也不允许丢和乱的,而TCP都做好了这层,自己也就没必要重复工作了


就是说 我发a[1] a[2] a[3] 那么只有可能顺序乱了 不可能出现包被分解是吧(a[1] a[2] a[3]肯定是一个整体) 是这意思吗?

#28


顺序都不会乱??

#29


估计你用的是socket函数写的
socket在传输的时候有的结构体可能接受的不完整,
要自己检查介绍到的字节数和结构体的size比较.
你可以用CSocket类来实现,可能不用关心这些细节.

#30


http://download.****.net/source/1777622

#31


我是用CSocket写的啊  CMysock继承的CSocket 自己稍微封装了下而已  这两天自己在写,现在可以传了

我现在只想知道 :
TCP 我发a[1] a[2] a[3]  接收端的情况可能是怎样?(不会乱序?,不会分包?)

UDP呢? 知道的说下好不?(这问题解决就结贴给分了)

#32


用tcp发送a[1],a[2],a[3]接受端不会乱序
但是,如果你的a[1]大小是1024,接受到的大小就有可能小于1024然后你需要再接受剩下的字节数.

#33


引用 32 楼 zhyhchg 的回复:
用tcp发送a[1],a[2],a[3]接受端不会乱序
但是,如果你的a[1]大小是1024,接受到的大小就有可能小于1024然后你需要再接受剩下的字节数.


我发a[1]a[2]a[3]
也就是说TCP发过来的肯定是 a[1]a[2]a[3]这样的顺序对吧
不会是a[1]a[3]a[2] 或者a[1] a[2]一部分 a[3] a[2]另一部分 这种情况吧。

UDP呢? 情况会很复杂?

#34


没处理沾包或未按顺序处理包!

#35


TCP是顺序是不会乱的,不过如果是没封装的Socket程序仍然需要处理分包,IP分片的大小如果大于1500就不能发送了。所以你的数据包应该控制到这个范围内,如果是支持外网特别是UDP发送的情况应该控制到1000左右,这个只是我个人测试时的经验数据。UDP发送时接收端收到的顺序可能会出现错误也就是你说的1 3 2的顺序,需要缓存以及给每个包编号然后还原数据顺序来处理。另外还可能出现丢包现象,如果是传送文件还需要你自己处理重发机制等等

#36


引用 24 楼 yaozhiyong110 的回复:
解决方法三、采用完成端口技术……  ?  什么东西??

完成端口就是重叠异步IO完成端口的简称,也就是IOCP,他只是一种通信模型,和select  WSAAnyncSelect  event等等是平级的,你可以先不管这个
发文件你可以选UPD和TCP都可以,UPD要麻烦得多,因为UPD可以丢包的,所以你得做校验,而且你第一次发的,他不一定是第一次收到的,也不一定能收全,但他的速度是最快的.TCP就简单多了,只要建一条连接,然后在服务端顺序读文件,并发给客户端,然后客户端顺序写文件就行了,不用做校验,也不用但心先发的后到,数据没收完等问题,但速度慢一点.如果你在局域网,或者在网络比较好的时候,你感觉不到的.

#37


建个议哈,如果初学,用TCP吧

#38


引用 35 楼 eyodo8 的回复:
TCP是顺序是不会乱的,不过如果是没封装的Socket程序仍然需要处理分包,IP分片的大小如果大于1500就不能发送了。所以你的数据包应该控制到这个范围内,如果是支持外网特别是UDP发送的情况应该控制到1000左右,这个只是我个人测试时的经验数据。UDP发送时接收端收到的顺序可能会出现错误也就是你说的1 3 2的顺序,需要缓存以及给每个包编号然后还原数据顺序来处理。另外还可能出现丢包现象,如果是传¡­


我嫌1024小啊 我都是 1024 * 16 一个包啊  会分包?
不过现在我的程序 顺序发 顺序接都没有问题哦 不过是在自己机子上 没有和别人机子测试

确定包大的话就会分包?

#39


我是用CSocket类的  算是封装了Socket的吧 应该不会分包了吧

#40


UDP 会不会出现 a[1] a[2]一部分 a[3] a[2]另一部分 这种情况?

#41


面向流的TCP才会出现你说的那种情况,UDP是面向包的。我没遇到过你说的那种情况,要么就是收不到。你用CSocket使用TCP时ms使用的Nagle算法可能会出现你说的那种情况。

#42


引用 41 楼 eyodo8 的回复:
面向流的TCP才会出现你说的那种情况,UDP是面向包的。我没遇到过你说的那种情况,要么就是收不到。你用CSocket使用TCP时ms使用的Nagle算法可能会出现你说的那种情况。


你说的我不懂

#43


说白了就是这个意思,做网络编程最好别用MFC的类,那东东不好用,初学最好用TCP,1次最好发1000字节左右,一般做网络编程得自己定义协议的,每一次发的数据是啥,第几次,校验码是啥是数据还是文件头信息,等等,也描术清楚,明白吗,如果不明白,加我QQ:372898309,来我们一起学习,怎么样 

#44


引用 31 楼 yaozhiyong110 的回复:
我是用CSocket写的啊  CMysock继承的CSocket 自己稍微封装了下而已  这两天自己在写,现在可以传了

 我现在只想知道 :
 TCP 我发a[1] a[2] a[3]  接收端的情况可能是怎样?(不会乱序?,不会分包?)

 UDP呢? 知道的说下好不?(这问题解决就结贴给分了)

你采用TCP的话,接收端是一般是不会出现乱序现象(除非发送缓冲区满了,发送数据被丢弃),只可能出现a[1]的一部分,a[1]的第二部分,.....a[1]的第n部分,a[1]的第n+1部分和a[2]的一部分,........,因此最好自己定义一个简单的通信协议,就是在每次发送时加入一个自定义的报头,接收时根据报头来接收。

#45


必须定义好接收方和发送方的协议格式,
还有就是必须处理粘包的问题。

#46


好了,也算有些体会了,谢谢大家帮忙,分就给登级低的吧,反正主要是交流,分又不重要的。
结贴喽。。。。

#47


LZ好象是初学者的,TCP和UDP还没有分清楚呢,最好先搞清楚这个再说。打个比方说吧,在应用层看来,TCP就象双方连立了一个通道,一端的东西流向另一端,可以当成是有序无差错的,但也是*的,没有包的概念,只是字节流,你要自己处理解析。而UDP就象有一个人不停地把东西打成包丢给你,你有可能能接收到,也有可能接收不到,也有可能他先丢的包你后接到,先丢的你先接到。但有一个好处,就是除非你不接到,如果你接到就是一整个包。

TCP的优点是稳定性好,缺点是占资源比较多;UDP的优点时速度快,缺点时稳定性差。具体那一个协议好?没有绝对的标准,只有哪一个更适应你的应用场景。象网络的语音和视频等,丢失一点数据不算什么大不了的事,所以一般采用UDP。对于交易数据或其它重要数据,当然就用TCP了。关于传文件这事,就不太好说了,基本上是功底不太好的就用TCP,毕竟比较简单,如果功底很好又愿意花时间的,就采用UDP了,因为如果处理得应的话,性能可以比TCP高一些。而且在某些应用环境里,只有UDP才能行得通。

回到你说的问题,你是以包为单位发的,看起来象是用UDP。但很明显,你没有对其做额外处理,这样传文件基本上是不可能成功(除非文件足够小,网络条件足够好)。当然这只是猜测了,说不定你是用TCP。如果是用TCP还有这个问题的话,那就是我前几天说的,发送太快造成发送缓冲区满。

#48


强调一下,“就是除非你不接到,如果你接到就是一整个包。”这句没有错,但就算你接到整个包也并不能保证包里的内容是正确的,你还需要进行一定的效验。其实,真实网络上传送的东西,都不能保证是对的,所以理论上都要自己进行效验。

#49


还有包的长度问题,一般情况过1400字节是可以的,但在某些情况下有可能通不过,我以前做的系统就出现过这个问题,但设置成1200就没有遇到过问题了。就算香港、*和大陆之间都没有问题。

#50


该回复于2010-11-26 15:25:40被版主删除