Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何确定从客户端到服务器(套接字)的文件传输(数据)结束_C#_Sockets_Client Server - Fatal编程技术网

C# 如何确定从客户端到服务器(套接字)的文件传输(数据)结束

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

简单情况:

套接字上的客户端以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);
     }

}
或者,我可以尝试向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
    });

发送文件之前先发送文件大小。如果可能,我希望一步完成所有操作