C#socket接收传送文件的数据流,只能得到大概4M的大小~求助啊

zpino 2011-04-22 09:58:40
C#socket接收传送文件的数据流,只能得到大概4M的大小。
如果一直读取文件的全部长度,当4M之后,用UE打开文件,发现后面保存的内容全部是0x00






socket的变量是temp

filelen=temp.Receive(datasize, 0, 4, SocketFlags.None);
int _filelen = BitConverter.ToInt32(filelen, 0); //通过读取自定义tcp头得前4个byte,获文件大小

int rescount = _filelen / packsiez; //获得要循环读取的次数
int lastpacksizi = _filelen % packsiez; //获得最后一个包的大小
if (lastpacksizi!=0)
{
rescount++;
}
string SendFileName = filesfolder + filename + ".rar"; //保存的文件名
int wcount=0;
using (FileStream MyFileStream = new FileStream(SendFileName, FileMode.Create, FileAccess.Write))
{
for (int i = 0; i <rescount; i++) //循环
{
if (temp.Connected)
{
if (i==rescount-1)
{
packsiez = lastpacksizi;
}
byte[] t=new byte[packsiez]; //声明一个byte数组
int counts= temp.Receive(t, 0, packsiez, SocketFlags.None); //接收内容
if (counts==0)
{
break;
}
MyFileStream.Write(t, 0, packsiez); //写入
wcount+=packsiez;
t = null;
}
else
{
break;
}
}
}
...全文
413 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qldsrx 2011-04-22
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zpino 的回复:]
我艹,写发包程序那sb,只发4M的包,开始我还和他争,说他只有4M,他死活不承认。今天跑去看那厮的源代码,就是只发4m的包。
真想爆他菊花。
!!!!!!!!!!!!!!!!!!!
[/Quote]
哈哈,发送方也有问题啊,不过我说的情况也是有的,你试试改判断接收的数据总量来完结接收,这样才合理。
qldsrx 2011-04-22
  • 打赏
  • 举报
回复
楼主你似乎没看懂啊,再仔细体味下我说的假设,如果你定义的packsiez=1024,相信接收应该没问题,但是你定义的实在太大了。另外丢包不会导致后面的全乱,因为TCP会重传前面丢包的部分的,如果丢的包不能补回来,后面的数据是不会继续发送的。
zpino 2011-04-22
  • 打赏
  • 举报
回复
我艹,写发包程序那sb,只发4M的包,开始我还和他争,说他只有4M,他死活不承认。今天跑去看那厮的源代码,就是只发4m的包。
真想爆他菊花。
!!!!!!!!!!!!!!!!!!!
zpino 2011-04-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qldsrx 的回复:]

楼上几位有没有仔细看问题啊,空谈道理谁都会,但不能解决问题。

楼主你的问题是你设计上的问题,定义的接收数组大小不合理。
我举例说明下,当你定义一个4M大小的byte[],但是temp.Receive方法一次接收最多只能4096字节的话(如果对方分包发送,估计每次发送1500字节以内都有可能),那么你在接收数据时,最多只填充4M内的前4096个字节,但是你以为填满了,于是“MyFileSt……
[/Quote]

按照你的方法,小于4M的文件传输没有问题了,传输的rar文件可以正常打开,之前是不打开的。
不过还是只有4100KB,难道是发送数据那边只发4M?
分先给你了,我研究研究去。
ever2010 2011-04-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qldsrx 的回复:]
楼上几位有没有仔细看问题啊,空谈道理谁都会,但不能解决问题。

楼主你的问题是你设计上的问题,定义的接收数组大小不合理。
我举例说明下,当你定义一个4M大小的byte[],但是temp.Receive方法一次接收最多只能4096字节的话(如果对方分包发送,估计每次发送1500字节以内都有可能),那么你在接收数据时,最多只填充4M内的前4096个字节,但是你以为填满了,于是“MyFileStr……
[/Quote]
我的Recive(byte[262144],0,262144),够长的了。,我发送的数据十几K左右,
而且如果用你这种方法,定义个count,如果中间丢包了,后面的包会不会全乱了
qldsrx 2011-04-22
  • 打赏
  • 举报
回复
楼上几位有没有仔细看问题啊,空谈道理谁都会,但不能解决问题。

楼主你的问题是你设计上的问题,定义的接收数组大小不合理。
我举例说明下,当你定义一个4M大小的byte[],但是temp.Receive方法一次接收最多只能4096字节的话(如果对方分包发送,估计每次发送1500字节以内都有可能),那么你在接收数据时,最多只填充4M内的前4096个字节,但是你以为填满了,于是“MyFileStream.Write(t, 0, packsiez);”,往文件里写了4M的内容,其实后面都是空的。此时带来另一个问题,如果按照你原来的设计,接收100M的文件只要调用25次循环执行Receive方法即可,但是实际发送方每次只发送4096字节的话,你需要调用25*1024次Receive方法才能收到完整的文件,因此你只接收了前面一小部分的内容,后面的数据被你主动放弃了。

修改建议:
看这段“ int counts= temp.Receive(t, 0, packsiez, SocketFlags.None); //接收内容",
那个返回值counts就是每次执行Receive后实际收到的字节数,只要将counts累加,看累加值是否等于之前告知的文件长度,相等就说明接收完毕,不等就继续接收。当然,写文件的方法和计数统计都要改为:
MyFileStream.Write(t, 0, counts); //写入
wcount+=counts;
ycproc 2011-04-22
  • 打赏
  • 举报
回复
首先 不用 一直读取文件的全部长度

然后你的缓冲区设置的多少
zpino 2011-04-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hhc123 的回复:]

没有linux的经验,但听说要转换什么来着?
好像什么位不一样。你google下
[/Quote]

不需吧?只听说过要转字节序什么来着,但是我获取到的数据貌似不需要转。都是正确的
hhc123 2011-04-22
  • 打赏
  • 举报
回复
没有linux的经验,但听说要转换什么来着?
好像什么位不一样。你google下
zpino 2011-04-22
  • 打赏
  • 举报
回复
补充一下,数据包是从linux发过来的。

110,531

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧