求助,关于异常处理

愤怒的豆沙包 2012-01-02 10:26:41
这是个socket文件传输的,每个文件包我设置了,最后10个byte存放文件包的编号,接收时按照这个编号写入,找到对应的位置

写入数据,一直没闹明白是什么原因导致文件包会出问题的,每次发送大的文件的时候,总会有个文件包出现莫名其妙的数据,

然后出现异常,我就想不理会这个异常,继续循环接收数据包,最后再检查缺少的数据包,进行补发。


然后就不知道具体怎么操作了,发送和接收端的代码如下~~ 求路过的大神帮忙,先谢谢了!!


////////////////////发送端
for (i = 0; i < packetCount; i++)
{
EzoneStream.Read(data, 0, packetSize - 10);
data = Convert.FromBase64String(Convert.ToBase64String(data)); /////
Array.Copy(Convert.FromBase64String(Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(i.ToString()))),
0,
data, packetSize - 10, Convert.FromBase64String(Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(i.ToString()))).Length);

client.Send(data);
}


//////////////////////////接收端
for (i = 0; i < packetCount; i++)
{
server.Receive(buff);
//提取文件包编号
Array.Copy(buff, buff.Length - 10, bInde, 0, bInde.Length);
inde = Convert.ToInt32(System.Text.Encoding.Unicode.GetString(bInde));
//设置文件指针并写入数据
Rec.Seek(inde * (packetSize - 10), SeekOrigin.Begin);
Rec.Write(buff, 0, buff.Length - 10);
che[inde] = 'y'; //标记已接收
}
...全文
64 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
愤怒的豆沙包 2012-01-03
  • 打赏
  • 举报
回复
那个我用base64转来转去,主要是开始的时候不知道怎么用二进制读写文件,后来实验到转为base64的时候对文件读写,传输就没问题了,才这么折腾的~~
愤怒的豆沙包 2012-01-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sp1234 的回复:]

“包”是你自己的概念吧。不要重复使用别人的名词儿,最好也不要重复使用底层通讯机制的名词(虽然.net的socket并不涉及这个词儿)。

你可以把它叫做一个“消息”,这就足够了。

你的代码我看不懂,为什么弄个base64转来转去的呢?你的那两行代码我实在是看不下去,你解释一下,也许我能在空腹是看下来。

如果打算为一个byte[]之前插入一个字节(保存编号),那么写C# code
……
[/Quote]


嗯嗯,第一次接触这东西,基础不怎么好,就只能凭感觉写东西了,貌似这次走错路了,那我再重写下代码吧, 谢谢你的解答了,我先结贴了,重新在整理下!!
  • 打赏
  • 举报
回复
因为有很多握手、发送、校验、确认之类的动作 --> 因为有很多握手、发送、校验、确认、重发之类的动作
  • 打赏
  • 举报
回复
对于tcp来说,其实你去增加一个序号是无必要的(除非有业务意义)。tcp可以保证正确的顺序接收消息,中间不丢掉任何一个字节。正因为此目的,tcp通讯启动非常缓慢,传输速度也很缓慢,因为有很多握手、发送、校验、确认之类的动作。不过它可以保证100%地正确次序,这也是它的特性。
  • 打赏
  • 举报
回复
“包”是你自己的概念吧。不要重复使用别人的名词儿,最好也不要重复使用底层通讯机制的名词(虽然.net的socket并不涉及这个词儿)。

你可以把它叫做一个“消息”,这就足够了。

你的代码我看不懂,为什么弄个base64转来转去的呢?你的那两行代码我实在是看不下去,你解释一下,也许我能在空腹是看下来。

如果打算为一个byte[]之前插入一个字节(保存编号),那么写
var copyData = new byte[data.Length + 1];
Array.Copy(data, 0, copyData, 1, data.Length);
copyData[0]=(byte)i;
这就足够了。

对于tcp来说所谓“沾包”这是常有的事。比如说你发送以个是8000个字节的消息,底层tcp通讯时可能分别按照每256个字节一个包去发送。尽管这些包有快有慢,有的走日本有的路由到爪哇岛然后才到达接收端,最后在接收端总之是按照正确的顺序可以receive到。但是假设你发送8000个字节之后立刻又发送9000字节,两个消息,那么对于底层来说当然还是把1700个字节的内容拆分成许多256字节的包来发送。

那么对于你的接收端,可能接收到7000个字节然后就反映为缓冲区中已经空了,然后过了50毫秒其实又有数据可以接受了,或者所谓的8000字节的结束边界并不存在,这当然都是很平常的事情了!


通常编写通讯程序,需要自己设计业务层的通讯协议。那种不设计通讯协议的,都是网上用来让你知道一点socket基本概念的小程序,经不起实际检验。
愤怒的豆沙包 2012-01-03
  • 打赏
  • 举报
回复
嗯嗯 谢谢了 那个我看过了,但是我主要是想做成可以检查能不能完整接收的,所以就加了后面的那个文件编号,

刚刚把数据包调小,发现问题了,貌似是两个数据包串包了,就是一半上个数据包,加上了一半下个数据包 组成了一个新的数据包,就又搞不明白了!!

实在无法理解怎么会发生这个问题!!

愤怒的豆沙包 2012-01-02
  • 打赏
  • 举报
回复
!!那个有句太长了 一直不知道怎么排版了!!


Array.Copy(Convert.FromBase64String(
Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(i.ToString()))), 0,data, packetSize -10,
Convert.FromBase64String(Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(i.ToString()))).Length);


就是这句了 就是将文件包编号写入数据包的最后1个字节中去的,不知道什么简单点的代码了 如果顺便帮忙提供个也万分感谢的 呵呵

110,533

社区成员

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

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

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