C# 如何确定从客户端到服务器(套接字)的文件传输(数据)结束
简单情况: 套接字上的客户端以byte[]格式向服务器发送一段(例如256字节)的文件数据。服务器异步接收数据。 如何确定文件数据何时完全传输?服务器端 以下是服务器端负责接收数据的代码C# 如何确定从客户端到服务器(套接字)的文件传输(数据)结束,c#,sockets,client-server,C#,Sockets,Client Server,简单情况: 套接字上的客户端以byte[]格式向服务器发送一段(例如256字节)的文件数据。服务器异步接收数据。 如何确定文件数据何时完全传输?服务器端 以下是服务器端负责接收数据的代码 public static void ReadCallback(IAsyncResult ar) { String content = String.Empty; // Retrieve the state object and the handler socket
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);
}
}
或者,我可以尝试向this byte[]对象添加一些信息,例如,一些带有标记的字符串
但我必须分析每一步的信息。
我可以更简单地检查一下吗?如何检查?或者使用另一种方法…唯一的方法是在每条消息前面发送一个特定大小的标题。因此,每条消息都应该由头和正文组成。数据流应如下所示:
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
});
[头][身体][头][一些更大的身体][头][一些超大的身体]
正如我所说的,头应该具有特定的大小,并且应该包含一些自定义服务字段,包括消息正文的大小(以字节为单位)。在您的情况下,标头只能包含正文大小,即int值4字节。接收过程应如下所示:
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
});
接收4字节报头;
从标题中检索主体大小,只需将标题转换为int;
接收标头中指定的字节数,即接收消息正文;
处理消息体;
转到1。
我知道,这对你来说可能很复杂,但这是通常的做法。但是您可以通过使用来简化代码。在为socket WhenRedexact实现了一些扩展方法之后,可以很容易地在Internet上找到实现,例如,代码如下所示:
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
});
发送文件之前先发送文件大小。如果可能,我希望一步完成所有操作