简单的情况:
Socket上的客户端以格式byte []
向服务器发送文件(数据)的片段(例如,256字节)。服务器异步接收数据。
如何确定文件(数据)何时完全传输? (服务器端)
这是服务器端负责接收数据的代码
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
BinaryWriter writer = new BinaryWriter(File.Open(@"D:\test.png", FileMode.Append));
writer.Write(state.buffer, 0, bytesRead);
writer.Close();
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket!",
bytesRead);
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
是否有一种方法可以让一些人跟随?
if (bytesRead > 0)
{
....
if(state.buffer!=end of receive)
{
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
或者,我可以尝试向此byte[]
对象添加一些信息(例如,带有<EOF>
标记的某些字符串)
但我必须分析每一步的信息。
我可以做这个检查更简单,怎么做?或者用另一种方式......
答案 0 :(得分:0)
唯一的方法是在每条消息前面发送一个标题(特定大小)。因此,每条消息应包含标题和正文。数据流应如下所示:
[HEADER] [BODY] [HEADER] [一些更大的身体] [HEADER] [一些额外的大身体]
正如我所说,标题应该是特定的大小,并且应该包含一些自定义服务字段,包括消息的主体大小(以字节为单位)。在您的情况下,标头只能包含主体大小,即int值(4个字节)。接收过程应如下所示:
我知道,对你来说这似乎很复杂,但这是常见的做法。但您可以使用Rx library来简化代码。在为socket实现一些扩展方法之后(WhenReadExact,可以通过Internet轻松找到实现,例如here),代码将如下所示:
var whenFileReceived = from header in socket.WhenReadExact(4)
let bodySize = BitConverter.ToInt32(header)
from body in socket.WhenReadExact(bodySize)
select body;
whenFileReceived.Subscribe(
file =>
{
// Handle file here
});