【问题标题】:c# file read and send over socketc# 文件读取和通过套接字发送
【发布时间】:2023-03-02 23:33:01
【问题描述】:

这就是我使用NetworkStream 发送文件的方式。

private void go()
{
    byte[] send = File.ReadAllBytes("example.txt");
    ns.Write(send, 0, send.Length);
}

ns 当然是NetworkStream

现在我想知道如何接收和读取传入的NetworkStream

我知道我需要像这样指定一个要从中读取的缓冲区,

ns.Read(buffer,0,buffer.length).

但应该有哪个缓冲区?

【问题讨论】:

  • 先发送缓冲区的长度,然后在接收时创建一个该大小的字节数组

标签: c# networking stream


【解决方案1】:

TCP 是一种基于流的协议,这意味着没有像 UDP 那样的应用程序消息符号。因此,您无法通过 TCP 本身真正检测到应用程序消息的结束位置。

因此,您需要引入某种检测。通常,您添加一个后缀(新行、分号或其他)或长度标题。

在这种情况下,添加长度标头会更容易,因为可以在文件数据中找到所选的后缀。

所以发送文件看起来像这样:

private void SendFile(string fileName, NetworkStream ns)
{
    var bytesToSend = File.ReadAllBytes(fileName);
    var header = BitConverter.GetBytes(bytesToSend.Length);
    ns.Write(header, 0, header.Length);
    ns.Write(bytesToSend, 0, bytesToSend.Length);
}

在接收方,检查 Read 的返回值很重要,因为内容可以分块出现:

public byte[] ReadFile(NetworkStream ns)
{
    var header = new byte[4];
    var bytesLeft = 4;
    var offset = 0;

    // have to repeat as messages can come in chunks
    while (bytesLeft > 0)
    {
        var bytesRead = ns.Read(header, offset, bytesLeft);
        offset += bytesRead;
        bytesLeft -= bytesRead;
    }

    bytesLeft = BitConverter.ToInt32(header, 0);
    offset = 0;
    var fileContents = new byte[bytesLeft];

    // have to repeat as messages can come in chunks
    while (bytesLeft > 0)
    {
        var bytesRead = ns.Read(fileContents, offset, bytesLeft);
        offset += bytesRead;
        bytesLeft -= bytesRead;
    }

    return fileContents;
}

【讨论】:

  • 非常感谢!如果我还想发送文件名并在另一边接收它? @jgauffin
  • 发送另一个标头指示文件名的大小。即
  • 你也可以使用我的 Griffin.Framework 中的网络库:github.com/jgauffin/griffin.framework
猜你喜欢
  • 2012-05-11
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
相关资源
最近更新 更多