C#socket接受二进制文件 如何知道已经全部接受完成了呢

云谣笑笑生 2012-10-28 10:57:02

class ClientState
{
public byte[] state = new byte[1024];
public Socket sk;
}
class FileState
{
public FileStream fs;
public string filename;
public const int length = 1024;
public byte[] state = new byte[length];
public Socket sk;
}
private void AsyCallback(IAsyncResult ar)
{
//获取侦听器
TcpListener tl = ar.AsyncState as TcpListener;
//获取客户端的Socket
sk = tl.EndAcceptSocket(ar);

ClientState cs = new ClientState();
cs.sk = sk;

sk.BeginReceive(cs.state, 0, cs.state.Length, SocketFlags.None, new AsyncCallback(Read_Callback), cs);
//异步接受数据
tl.BeginAcceptSocket(new AsyncCallback(AsyCallback), tl);

}

public void Read_Callback(IAsyncResult ar)
{
ClientState cs = (ClientState)ar.AsyncState;
Socket s = cs.sk;

int read = s.EndReceive(ar);
byte[] fnl = cs.state;
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
ms.Write(fnl, 0, fnl.Length);
ms.Position = 0;
ArrayList aal = (ArrayList)bf.Deserialize(ms);
FileState fstate = new FileState();
fstate.filename = aal[1] as string;
fstate.sk = s;
fstate.fs = new FileStream(@"C:\Users\Administrator\" + fstate.filename, FileMode.OpenOrCreate, FileAccess.Write);
s.BeginReceive(fstate.state, 0, FileState.length, 0, new AsyncCallback(ReceMsgCallBack), fstate);

}

public void ReceMsgCallBack(IAsyncResult ar)
{
FileState cs = ar.AsyncState as FileState;
Socket thisSk = cs.sk;
int read = thisSk.EndReceive(ar);
if (read>0)
{

cs.fs.Write(cs.state, 0, read);
thisSk.BeginReceive(cs.state, 0, FileState.length, 0, new AsyncCallback(ReceMsgCallBack), cs);

}
else
{

cs.fs.Write(cs.state, 0, read);
ClientState tcs = new ClientState();
tcs.sk = thisSk;
cs.fs.Close();
sk.BeginReceive(tcs.state, 0, tcs.state.Length, SocketFlags.None, new AsyncCallback(Read_Callback), tcs);
}


}
经过修改该这是接受的代码 首先客户端先发送序列化的文件名过来 然后再发送文件过来 但我读取的时候 第一次接受个图片还可以 但第二次就不行了 不知道怎么回事 求大神求解
...全文
396 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
u010135738 2013-08-05
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
在你的程序中,只是“传送”文件内容字节。这其实是网络上那些极端不负责任的所谓“通讯范例”程序惯用的代码。

但是任何一个实用的通讯程序,其实最起码地,都需要从“设计信令格式”做起。不可能只是传送一堆文件内容二进制,而是需要将一个个信令消息封装在自定义的数据结构内。有了这个知识,你才能开始设计通讯程序。
  • 打赏
  • 举报
回复
人家的设计是针对消息缓冲区里有多个独立消息的,你那个程序只有一个简单的消息。但是你的程序只是简单的文件内容,既没有传送其它属性,也没有传送结束标志。

一个简单的.net解析post文件数据的源程序可以参考看:

http://www.haogongju.net/art/581849
kensouterry1 2012-10-28
  • 打赏
  • 举报
回复
自己组织数据结构(设置状态),封装类
传文件的时候对文件的每块MD5执行验证,当传到Finish状态时,最后一次对两个文件的MD5做验证。如果相同就表示文件已经传输完毕
gwhzh 2012-10-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

在rfc2183中定义了一种在http中post内容(包括上传文件)的协议,很简单,例如:


Assembly code
--------------- akldf kakfaskdfasda
Content-Disposition: form-data; name="小电影"; filename="mao1234.mp4"

xxxxxxxxxxxxxxxxxxxxxxxxxxx..……
[/Quote]
需要自己定义字符来处理。
wuyq11 2012-10-28
  • 打赏
  • 举报
回复
接收出现错误可能是粘包问题
  • 打赏
  • 举报
回复
在rfc2183中定义了一种在http中post内容(包括上传文件)的协议,很简单,例如:


--------------- akldf kakfaskdfasda
Content-Disposition: form-data; name="小电影"; filename="mao1234.mp4"

xxxxxxxxxxxxxxxxxxxxxxxxxxx.....一堆二进制代码
--------------- akldf kakfaskdfasda
Content-Disposition: form-data; name="参数1"

3.1415926

--------------- akldf kakfaskdfasda--


也就是说,数据和数据之间是有分割字符串来区分其开始结束的。这样在你收到数据时,需要将数据(往往是多次Receive操作所累积起来的,因为中间会有类似“粘包”的数据)分解为多个独立的消息,再处理。
云谣笑笑生 2012-10-28
  • 打赏
  • 举报
回复
嗯 不懂啊 能不能给点例子啊
XBodhi. 2012-10-28
  • 打赏
  • 举报
回复
SOKECT不是有 Revalce 吗,返回 0 就是失败了
XBodhi. 2012-10-28
  • 打赏
  • 举报
回复
异步处理,
wuyq11 2012-10-28
  • 打赏
  • 举报
回复
一般判断Socked对象的Available属性,结合循环不是太准确
自己定义数据帧,自己组织数据包进行传递
一个包长度|总包数|第几包|值|检验

110,534

社区成员

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

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

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