在BinaryReader中是否有自动的端序检测?
本文关键字:检测 BinaryReader 是否 | 更新日期: 2023-09-27 18:14:59
我正在开发一个客户端,它使用一个非常简单的协议通过TCP连接生成和传输位图:
- [步骤1]发送文件大小为n的字节作为Int64
- [步骤2]发送n个字节表示位图数据
为了在开发过程中帮助我,我实现了一个简单的服务器,它等待连接,在客户端发送文件时接受文件,并使用随机生成的文件名
将它们存储在HDD上using System;
using System.Text;
using System.IO;
using System.Net.Sockets;
namespace SimplePictureReceiverServer
{
class Program
{
private static Int32 PORT = -1;
private static String DirSaveTo = null;
static void Main(string[] args)
{
// Ensuring that required parameters have been provided
if (args.Length < 2) { ShowUsage("Parameter-Count"); return; }
if (!Int32.TryParse(args[0], out PORT)) { ShowUsage("<port>"); return; }
if (!Directory.Exists(args[1])) { ShowUsage("<dir>"); return; }
PORT = Int32.Parse(args[0]);
DirSaveTo = args[1];
// Setting up the Server on <127.0.0.1>:<PORT>
TcpClient c = null; NetworkStream s;
TcpListener l = new TcpListener(System.Net.IPAddress.Loopback, PORT);
l.Start();
while(true)
{
// Waiting for a Client to connect
Console.Write("Waiting ... ");
c = l.AcceptTcpClient();
s = c.GetStream();
Console.WriteLine("Ok");
// Handle the client
try
{
using (BinaryReader r = new BinaryReader(s, Encoding.Unicode))
{
HandleClient(r);
}
}
catch(Exception e)
{
Console.WriteLine("Client disconnected (" + e.Message + ")");
Console.WriteLine();
}
}
}
private static void ShowUsage(String s)
{
Console.WriteLine("Problem with " + s);
Console.WriteLine();
Console.WriteLine("USAGE 't program.exe <port> <dir>");
Console.WriteLine("<port> : Port to listen to when waiting for connections");
Console.WriteLine("<dir> : Directory to store received pictures at. The directory must exist");
Console.WriteLine();
Console.WriteLine("Press [ENTER]");
Console.ReadLine();
}
private static void HandleClient(BinaryReader r)
{
const Int32 BUF_SIZE = 10 * 1024;
Int32 cntPicutresReceived = 0; StringBuilder b = new StringBuilder();
Random rnd = new Random();
Byte[] buf;
Int32 bytesLeftToRead;
while (true)
{
using (MemoryStream m = new MemoryStream())
{
// Reading picture size and picture from stream
bytesLeftToRead = Convert.ToInt32(r.ReadInt64()); // Reading size as Int32
// Little/ Big Endian - Consider !
Console.WriteLine("Expected filesize is " + bytesLeftToRead.ToString("#,##0") + " Bytes");
while (bytesLeftToRead > 0) // Reading the picture
{
buf = r.ReadBytes(Math.Min(BUF_SIZE, bytesLeftToRead));
m.Write(buf, 0, buf.Length);
bytesLeftToRead = bytesLeftToRead - buf.Length;
}
// Storing picture on HDD with a fancy filename created in the StringBuilder
m.Seek(0L, SeekOrigin.Begin);
b.Clear();
b.Append((++cntPicutresReceived).ToString("0000"));
b.Append("__");
b.Append(rnd.Next(Int32.MaxValue).ToString("X"));
b.Append(".bmp");
using (FileStream f = new FileStream(Path.Combine(DirSaveTo, b.ToString()), FileMode.Create))
{
m.CopyTo(f);
}
Console.WriteLine("Image saved at '" + Path.Combine(DirSaveTo, b.ToString()) + "'");
}
}
}
}
}
为了测试服务器,我实现了一个test - client,它生成5个随机位图并将它们发送到服务器
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net.Sockets;
namespace SimplePictureSender
{
class Program
{
static Random Random = new Random();
static void Main(string[] args)
{
Bitmap b;
TcpClient c = new TcpClient("127.0.0.1", 12345);
Stream s = c.GetStream();
using (BinaryWriter w = new BinaryWriter(s))
{
for (Int32 i = 0; i < 5; i++)
{
using (MemoryStream m = new MemoryStream())
{
b = CreateRandomBitmap(640, 480, 1000, 1000); b.Save(m, ImageFormat.Bmp);
Console.WriteLine("Picture size is " + m.Length + " Bytes"); Console.WriteLine();
m.Seek(0L, SeekOrigin.Begin);
w.Write(m.Length);
m.WriteTo(w.BaseStream);
}
}
}
Console.WriteLine("[ENTER] to exit");
Console.ReadLine();
}
private static Bitmap CreateRandomBitmap(Int32 minX = 100, Int32 minY = 100, Int32 maxDeltaX = 250, Int32 maxDeltaY = 250)
{
Console.Write("Generating Picture ... ");
Bitmap b = new Bitmap(Random.Next(minX, minX + maxDeltaX), Random.Next(minY, minY + maxDeltaY));
Color c;
for(Int32 x = 0; x < b.Width; x++)
for(Int32 y = 0; y < b.Height; y++)
{
c = Color.FromArgb(Random.Next(0, 256), Random.Next(0, 256), Random.Next(0, 256));
b.SetPixel(x, y, c);
}
Console.WriteLine("Done");
return b;
}
}
}
这一切都工作得很好…出奇的好。
如果我将服务器上的using (BinaryReader r = new BinaryReader(s, Encoding.Unicode))
行替换为以下内容之一
-
using (BinaryReader r = new BinaryReader(s, Encoding.BigEndianUnicode))
-
using (BinaryReader r = new BinaryReader(s))
设置总是成功地传输和存储位图。然而,我希望这些代码中至少有一个失败,因为服务器应该无法正确提取以下数据blob的大小。
为什么它工作?是否有一个隐含的端序检测?如果现在我要用C语言实现客户端,我需要担心端序吗?如果不是,我的服务器期望什么?
参见BinaryReader构造函数。
encoding形参称为"字符编码",显然对如何将整数写入流没有影响。
如果您的客户端和服务器端具有相同的端序,那么无论字符编码是什么,代码都可以工作,因为您没有向流写入任何字符,只是字节。