文件传输套接字编程
本文关键字:编程 套接字 传输 文件 | 更新日期: 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-serialization
和encryption
/decryption
的数据- 你可以使用
BinaryFormatter
或编写自己的序列化器,你可以序列化到二进制数据,XML, JSON或任何其他你想要的格式,但你应该想让序列化器处理这个,而不是像你刚才做的那样在你的应用程序代码。
- 你可以使用
-
Application Layer
,它将负责数据的对象表示,并允许您在不改变通信层的情况下抽象地更改数据(通过实现匹配objects
和classes
来使用)- 为文件表示创建一个类,它将包含:
- 文件名。
- 文件数据。
- 卷号码。
- 您想要的任何其他应用数据
- 为文件表示创建一个类,它将包含:
这样你就可以创建新的消息类型,如果你需要不改变你的整个模型和设计(如,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)。