文件传输套接字编程

本文关键字:编程 套接字 传输 文件 | 更新日期: 2023-09-27 18:14:41

我用c#编写了一个文件传输程序。我写过服务器和客户端程序。现在我想做一些额外的事情。我想发送用户的卷号(例如:1,2,3等)以及将在服务器端接收的客户端程序的IP地址。我该怎么做呢?我的示例客户机程序代码如下所示:

class Program
{
    static void Main(string[] args)
    {
        try
        {    
            string roll ="1";
            string fileName = @"D:'demo.txt";
            TcpClient tcpClient = new TcpClient("127.0.0.1", 1234);
            Console.WriteLine("Connected. Sending file.");
            StreamWriter sWriter = new StreamWriter(tcpClient.GetStream());                
            byte[] bytes = File.ReadAllBytes(fileName);
            sWriter.WriteLine(bytes.Length.ToString());
            sWriter.Flush();
            sWriter.WriteLine(fileName);
            sWriter.Flush();
            Console.WriteLine("Sending file");
            tcpClient.Client.SendFile(fileName);
        }
        catch (Exception e)
        {
            Console.Write(e.Message);
        }
        Console.Read();
    }
}

我还需要添加哪些内容?

文件传输套接字编程

根据OSI模型,TCP只负责transport/session级别的通信,为了实现客户端服务器之间的完整通信,您需要在您的TCP通信上定义您自己的应用协议

为此,您需要一些东西:

  • 表示层,它将负责serialization/de-serializationencryption/decryption的数据
    • 你可以使用BinaryFormatter或编写自己的序列化器,你可以序列化到二进制数据,XML, JSON或任何其他你想要的格式,但你应该想让序列化器处理这个,而不是像你刚才做的那样在你的应用程序代码
  • Application Layer,它将负责数据的对象表示,并允许您在不改变通信层的情况下抽象地更改数据(通过实现匹配objectsclasses来使用)
    • 为文件表示创建一个类,它将包含:
      • 文件名。
      • 文件数据。
      • 卷号码。
      • 您想要的任何其他应用数据

这样你就可以创建新的消息类型,如果你需要不改变你的整个模型和设计(如,reset roll message等…)。

您可以设计一个小协议。这里有一个基本的例子,可以让你知道如何开始。假设我们想发送一个float值:

using (BinaryWriter writer = new BinaryWriter(sWriter, Encoding.UTF8))
{
    var floatValue = 23.4F;
    var bytes = new List<byte>();
    bytes.Add(0x03) // type of message: float
    bytes.Add(BitConverter.GetBytes(floatValue)); // 4 bytes of float
    writer.Write(bytes.ToArray());
}

在另一边,你可以这样解释信息:

switch (receivedArray[0])
    case 0x03: return BitConverter.ToSingle(receivedArray, 1);
               break;

但是,您可能希望支持更多类型的数据,可能是整个对象等等。您可能希望扩展支持的数据类型,以引入可变长度字符串等。

using (BinaryWriter writer = new BinaryWriter(sWriter, Encoding.UTF8))
{
    var bytes = new List<byte>();
    var floatValue = 23.4F;
    var ip = "192.168.111"
    var stringBytes = Encoding.ASCII.GetBytes(string);
    bytes.Add(0x03) // type of message: string
    bytes.Add(BitConverter.GetBytes(stringBytes.Length)); // 8 bytes with length
    bytes.AddRange(stringBytes); // entire string
    writer.Write(bytes.ToArray());
}

对于高级场景,你应该考虑Protobuf或其他序列化框架,它们可以更容易地使用对象来处理数据,而不是原始浮点数和字符串(这适用于工业低级协议,如Modbus)。