我是一名Java开发人员而非C#开发人员,但我使用这两种语言;不幸的是,我在任何一种语言中都没有达到大多数人的水平,但这就是为什么我不断提问和阅读以扩展我的知识。
目前我一直在使用Java中的服务器/客户端工作非常好,我已经用Java编写了一个测试客户端,用于我在Unity3D中工作的游戏。老实说,如果社区在那里轻松获得关卡设计师等,我会在整个游戏中使用Java。
在此代码中,我在java中使用BufferedInputStream,设置如下:
DataInputStream dataIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
在整个代码中,我执行以下逻辑来检查以确保指定数据包的所有数据都已到达:
if(dataIn.available() < 4) {
continue;
}
dataIn.mark(4);
int length = dataIn.readInt();
System.out.println("Packet length is" + length);
if(dataIn.available() < length) {
System.out.println("Only read " + dataIn.available() + "/ " + length + " bytes.");
dataIn.reset();
continue;
}
我一直在努力在C#中找到与之相当的东西。 - 我注意到的其他问题是java的DataOutputStream发送的字节和C#的BinaryReader读取的字节并不总是相同,但这是另一个问题
答案 0 :(得分:1)
这样的内容会读取内存流中的所有预期数据。通过将内存流用作流,或通过使用memoryStream.ToArray()获取其中的字节,可以进一步处理接收到的数据。
using (var ns = new NetworkStream(socket))
{
int dataLength = 0;
// reading the datalength
for (int i = 0; i < 4; i++)
{
while (!ns.DataAvailable)
{
System.Threading.Thread.Sleep(20);
}
dataLength = (dataLength << 8) + ns.ReadByte();
}
// reading the data
byte[] buffer = new byte[1024];
int bytesRead;
using (var memoryStream = new MemoryStream())
{
while (memoryStream.Length < dataLength)
{
while (!ns.DataAvailable)
{
System.Threading.Thread.Sleep(20);
}
bytesRead = ns.Read(buffer, 0, buffer.Length);
memoryStream.Write(buffer, 0, bytesRead);
}
}
}
编辑:简约方法
使用这种方法时要小心socket.ReceiveBufferSize!如果它小于数据大小,那么你需要长时间睡眠。
Socket socket = listener.AcceptSocket();
while (socket.Available < 4)
{
System.Threading.Thread.Sleep(20);
}
byte[] lengthBuffer = new byte[4];
socket.Receive(lengthBuffer);
if (BitConverter.IsLittleEndian) Array.Reverse(lengthBuffer);
int dataLength = BitConverter.ToInt32(lengthBuffer, 0);
while (socket.Available < dataLength)
{
System.Threading.Thread.Sleep(20);
}
byte[] dataBuffer = new byte[dataLength];
socket.Receive(dataBuffer);