socket接收byte[]

minchieh 2010-11-24 10:07:11
public class ClassMsg
{
public String sendkind="";//标识发送状态,如果是"start",表示要准备发送,如果是"sending",说明数据已经开始在发了,如果是"end",说明发完了,start和end时Data是空数据,数据只在sending状态发送

public String FileName = "";//文件名

public byte[] Data;//文件转化成byte[]流,并且切成很多份
}

服务器通过socket不停的发送一个对象ClassMsg到客户端来传送一份文件,
客户端在接受的时候:
分3部写:

switch(ClassMsg.sendkind)
{
case start:
{
FileStream fs= File.Create(ClassMsg.FileName);//新建文件名为FileName的文件
break;
}
case sending:
{
FileStream fs=File.OpenWrite(ClassMsg.FileName);//将本地未接受完的文件载入到fs中
fs.Seek(0, SeekOrigin.End);//将该流的当前位值设为0
fs.Write(ClassMsg.Data, 0, ClassMsg.Data.Length);//向文件中写入当前接收的信息
break;
}
case end:
{
this.textbox1.text="收到新文件:"+ClassMsg.FileName;
break;
}
}

按照我上面写的,因为每次接受到数据都新建了一个空白的fs,将接受的数据写到相应文件名的文件中,这样比较灵活,可以同时几个人一起传文件,反正fs中没有残留信息,但是问题也出现了,在接受的过程中,每次新建fs,fs还得从机器上载入未传完的文件,文件超过600K的时候,好像载入的非常慢,载入的数据跟不上服务器向客户端发送数据包的速度,然后后面的数据就丢失了,整份文件只传了600K

怎么解决?
...全文
255 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunzhi523 2010-11-24
  • 打赏
  • 举报
回复
以后多多交流 哦。。。
  • 打赏
  • 举报
回复
另外,似乎你的所谓客户端只是被一个服务器推送文件似的,这也很可能是协议设计中的一个bug。
  • 打赏
  • 举报
回复
其实很多时候这种“服务器、客户端”的说法我看着很诧异。

按照tcp通讯,凡是作为监听的就叫做服务器,而服务器完全可以同时也作为客户端。所以你叫做客户端的机器,它在一个任务中其实是服务器;而你叫做服务器的机器,此时其实是客户端。

[Quote=引用 3 楼 duoluoo 的回复:]
我data[]的大小是1024个,也就是1K的数据
如果我发送600K以下的数据,很顺利,但是超过600K的,数据就丢失了

我个人感觉是FileStream fs=File.OpenWrite(...);的速度跟不上,服务器socket过来的速度,socket过来的数据又没在内存中保存进行异步读取,服务器不管客户端读取速度跟不跟的上,反正盲目的发数据包
[/Quote]

单机上“开发”就容易这样瞎试。你仔细想一下就能想出一种测试用例,网络差一些,或者某台机器忙一些,不可能盲目匹配上处理速率。更何况你的接收数据的那一端根本没有验证data的偏移地址,而是盲目地放到文件尾去写,这样如何能够检测出丢失的data?

实际上真正的传文件,每传送一小块数据都需要确认,发送端没有收到确认则需要重发,重发许多次之后还没有收到确认则传输失败。不要被网上的某些幼稚的socket的“范例”给骗了。你仔细想一想,想好“协议”,不要简单化。
zjx198934 2010-11-24
  • 打赏
  • 举报
回复
用多线程来处理 得到的每一个请求 都开一个线程来进行写文件操作
ThreadPool.QueueUserWorkItem(delegate {调用写文件方法 });
然后在获取流的时候 循环读取 将大于1024的情况也考虑进去!
minchieh 2010-11-24
  • 打赏
  • 举报
回复
我data[]的大小是1024个,也就是1K的数据
如果我发送600K以下的数据,很顺利,但是超过600K的,数据就丢失了

我个人感觉是FileStream fs=File.OpenWrite(...);的速度跟不上,服务器socket过来的速度,socket过来的数据又没在内存中保存进行异步读取,服务器不管客户端读取速度跟不跟的上,反正盲目的发数据包
minchieh 2010-11-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyazhe 的回复:]

用完能否关闭了stream?
[/Quote]
对, 我用一次 就关闭一次的。忘了写出来了,多谢提醒
在start和sending的时候 ,用完都fs.close();的

问题依旧
兔子-顾问 2010-11-24
  • 打赏
  • 举报
回复
用完能否关闭了stream?

111,129

社区成员

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

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

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