关于TCP/IP传送文件过程:
1. 传送文件名(有长度前缀的字符串); 2. 传送文件大小(INT64类型); 3. 传送具体内容;
其中所谓有长度前缀的字符串,就是在发送字符串之前先发送字符串的长度,收发两端都会有对长度的处理函数。而这个长度是以7bit编码的,也就是说长度数据中改到每一个字节中最高位无效。具体可参见解析了mscorlib.dll库中的System.IO.BinaryWriter的成员函数的代码,如下所示:
public virtual unsafe void Write(string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
int byteCount = this._encoding.GetByteCount(value);
this.Write7BitEncodedInt(byteCount);
if (this._largeByteBuffer == null)
{
this._largeByteBuffer = new byte[0x100];
this._maxChars = 0x100 / this._encoding.GetMaxByteCount(1);
}
if (byteCount <= 0x100)
{
this._encoding.GetBytes(value, 0, value.Length, this._largeByteBuffer, 0);
this.OutStream.Write(this._largeByteBuffer, 0, byteCount);
}
else
{
int num4;
int num2 = 0;
for (int i = value.Length; i > 0; i -= num4)
{
num4 = (i > this._maxChars) ? this._maxChars : i;
fixed (char* str = ((char*) value))
{
int num5;
char* chPtr = str;
fixed (byte* numRef = this._largeByteBuffer)
{
num5 = this._encoder.GetBytes(chPtr + num2, num4, numRef, 0x100, num4 == i);
str = null;
}
this.OutStream.Write(this._largeByteBuffer, 0, num5);
num2 += num4;
}
}
}
}
protected void Write7BitEncodedInt(int value) { uint num = (uint) value; while (num >= 0x80) { this.Write((byte) (num | 0x80)); num = num >> 7; } this.Write((byte) num); } |
第二步中的发送文件大小是按先发送低字节再发送高字节为顺序的,对应的解析该文件大小的函数可以是BinaryReader.ReadInt64()或BinaryReader.ReadInt32()等,其读入过程反过来,即先读入低字节再读入高字节。
测试代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace TestBinaryReaderClass_ReadString
{
class Program
{
static void Main(string[] args)
{
string path = System.IO.Directory.GetCurrentDirectory() + "\\123.txt";
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
char cha;
int num;
double doub;
string str;
try
{
byte[] bAll = br.ReadBytes(2000);
br.Close();fs.Close();
foreach (byte b0 in bAll)
Console.Write(b0.ToString() + " ");
Console.Write("\n\n");
foreach (byte b0 in bAll)
Console.Write(((char)b0).ToString() + " ");
Console.Write("\n\n");
fs = new FileStream(path, FileMode.Open, FileAccess.Read);
br = new BinaryReader(fs);
cha = br.ReadChar();
num = br.ReadInt32();
doub = br.ReadDouble();
Console.WriteLine("{0},0x{1},{2}\n", cha, num.ToString("X"), doub);
byte[] b = BitConverter.GetBytes(doub);
foreach ( byte b0 in b)
Console.Write(b0.ToString() + " ");
Console.Write("\n\n");
str = br.ReadString();
Console.WriteLine("{0},{1},{2},{3}\n", cha, num, doub, str);
}
catch (EndOfStreamException e)
{
Console.WriteLine(e.Message);
Console.WriteLine("已经读到末尾");
}
finally
{
Console.ReadKey();
}
}
}
}
其中123.txt已事先写入
