我需要你的帮助、意见和正确的方法来完成我的项目(服务器客户端,但我一直停留在数据对话和通用类型中)
本文关键字:一直 客户端 服务器 停留在 数据 类型 对话 我的 帮助 需要你 要你的 | 更新日期: 2023-09-27 18:25:55
好吧,这会很长。
首先,我想向你介绍我确实需要什么:
我需要建议,你的意见,正确的方法背后的服务器客户端数据发送&接收(如果我在某个时候错了)
需要修复我卡住的地方(我已经指出了)
首先,我制作了一个类,它实际上是一个用于发送&接收数据。我的意思是有这样的方法:
void Write(byte arg)
void Write(ushort arg)
void Write(DateTime arg)
void Write(DateTime[] arg)
byte ReadByte()
int[] ReadIntArray(int count)
等等。等等。这种方法实际上向CCD_ 1写入字节。还有一些方法,比如Send()通过流发送数据,Clear()清除缓冲区。
public void Clear()
{
motherBuffer.Clear();
}
public void Send()
{
Stream.Write(motherBuffer.ToArray(), 0, motherBuffer.Count);
}
首先,我班的逻辑是这样的:
public void Write(byte arg)
{
motherBuffer.Add(arg)
}
public void Write(short arg)
{
foreach (byte b in BitConverter.GetBytes(arg)) // calls Write(byte) twice
Write(b);
}
public byte ReadByte()
{
if (!IsDataAvailable())
throw new Exception("No-data is available to be read.");
else
return (byte)Stream.ReadByte();
}
public short ReadShort()
{
return BitConverter.ToInt16(new byte[2] { ReadByte(), ReadByte() }, 0); // calls readbyte twice
}
public short[] ReadShortArray(int length)
{
short[] r = new short[length];
for (int i = 0; i <= length - 1; i++)
r[i] = ReadShort();
return r;
}
但在我发现有更好的方法后,我改变了这个方法,比如:
public void Write(byte arg)
{
motherBuffer.Add(arg);
}
public void Write(byte[] arg)
{
motherBuffer.AddRange(arg);
}
public void Write(short arg)
{
Write(BitConverter.GetBytes(arg)); // this time only calls Write(byte[]) once
}
public byte ReadByte()
{
if (!IsDataAvailable())
throw new Exception("No-data is available to be read.");
else
{
int read = Stream.ReadByte();
if (read < 0)
throw new Exception("End of stream -1");
else
return (byte)read;
}
}
public byte[] ReadByteArray(int count)
{
if (!IsDataAvailable())
throw new Exception("No-data is available to be read.");
else
{
byte[] read = new byte[count];
int result = Stream.Read(read, 0, count);
if (result <= 0)
throw new Exception("End of stream -1");
else
return read;
}
}
public short ReadShort()
{
return BitConverter.ToInt16(ReadByteArray(2), 0); // this time calls once too
}
public short[] ReadShortArray(int length)
{
short[] r = new short[length];
for (int i = 0; i <= length - 1; i++)
r[i] = ReadShort();
return r;
}
在这一切之后,我想我为什么不做这样的事情(我真的很难过,因为这是一条更短的路,也是我将要陷入困境的地方):
public T Read<T>() where T : int // I don't actually know what 'where T : int' does just tried for 'return (int)-1;'
{
if (!IsDataAvailable())
throw new Exception("No-data is available to read.");
if (typeof(T) == typeof(byte))
{
int read = Stream.ReadByte();
if (read < 0)
return (int)-1; // STUCK HERE
else
return read as T; // STUCK HERE
}
else
{
// STUCK HERE : because I don't know how to return & convert type of 'T'
}
}
public int ReadArray<T>(T[] buffer, int offset, int count)
{
if (!IsDataAvailable())
throw new Exception("No-data is available to read.");
if (typeof(T) == typeof(byte))
{
return Stream.Read(buffer as byte[], offset, count);
}
else
{
int m = 2; // multplier for example: this is short. I didn't figure out how to get it like sizeof(T)
byte[] byteBuffer = new byte[count * m]; // because I have to read twice amount of byte
ReadArray<byte>(byteBuffer, 0, byteBuffer.Length);
// I really don't know how could I use T with BitConverter.GetBytes( of T );
}
}
不要使用泛型,在这种情况下它们是你的敌人。只需编写您想要的代码,然后继续前进。真正可以改进的是使用WCF或Remoting进行网络通信,而不是手动封送处理。
这是实现Read的一种方法:
public static T Read<T>(this Stream stream)
{
object ret = null;
if (typeof(T) == typeof(byte))
ret = stream.ReadInt8();
else if (typeof(T) == typeof(Int16))
ret = stream.ReadInt16();
else if (typeof(T) == typeof(Int32))
ret = stream.ReadInt32();
if (ret == null)
throw new ArgumentException("Unable to read type - " + typeof(T));
return (T)ret;
}
public int ReadArray<T>(this Stream stream, T[] buffer, int offset, int count)
{
for (int i = offset; i< count; i++) buffer[i] = stream.Read<T>();
}
您可能想了解一下WCF,因为它已经比您所能更好地解决了这个问题,并且可以让您直接关注应用程序逻辑,而不必担心如何在层之间移动数据;这是我能找到的最短的WCF示例,希望它能帮助
我知道这篇文章已经发布一年了,但我认为它值得添加到.
好吧,首先,正如几乎所有人都说的那样,使用WCF或其他已经实现并测试过的系统在层之间进行通信。
但要填补你的空白:
where T : int
是一个通用约束,表示您将只返回一个int
。如果int
被替换为类似Stream
的类,那么您是在说您将只返回Stream
或从Stream
派生的类。
因为您有一个int
的通用约束,所以typeof(T)
永远不会等于List<byte> motherBuffer
0。
as
运算符只能用于类而不能用于结构。由于int
的一般约束,T
是struct
。
我可以告诉您,要解决return (int)-1;
的问题,您需要先转换为object
,然后再转换为T
,就像return (T)(object)-1;
一样。但我真的无法解释为什么,因为我还没有完全理解这一点。我可以为你指出Generics中的协方差和逆变换的方向http://msdn.microsoft.com/en-us/library/dd799517.aspx.
我希望你觉得这很有帮助。