java通过网络写入数据
我正在用C#开发一个基本的网络实现,它将允许我向Java服务器发送数据。该服务器已经测试了相当长的一段时间,它可以用Java客户机完成所有需要做的事情,现在我正在尝试学习C#客户机开发
我遇到的问题是,服务器将我通过C#client发送的每个数据包操作码都读取为0,因此不执行任何逻辑。数据在服务器上以字节的形式读取。这是我的设置
public class NetworkClient {
public static NetworkClient Create() {
return new NetworkClient ();
}
private Queue<Task> tasks = new Queue<Task>();
private String HostAddress = "localhost";
private int Port = 5055;
private TcpClient _tcpClient;
private NetworkStream _networkStream;
private NetworkClient() {
}
public void Update() {
while (tasks.Count > 0)
tasks.Dequeue () ();
}
public void Submit(Task task) {
tasks.Enqueue (task);
}
public NetworkClient SetPort(int port) {
Port = port;
return this;
}
public NetworkClient SetHostAddress(String hostAddress) {
HostAddress = hostAddress;
return this;
}
public NetworkClient Connect() {
_tcpClient = new TcpClient (HostAddress, Port);
_networkStream = _tcpClient.GetStream ();
return this;
}
public bool IsConnected() {
return _tcpClient.Connected;
}
public NetworkClient Disconnect() {
_tcpClient.Close ();
return this;
}
public void Write(Packet packet) {
_networkStream.Write (packet.buffer.ToArray (), 0, (int)packet.buffer.Length);
}
}
以下是数据包类:
public class Packet {
public int Opcode;
public MemoryStream buffer;
public static Packet Create(int opcode) {
return new Packet (opcode, 128);
}
public static Packet Create(int opcode, int capacity) {
return new Packet (opcode, capacity);
}
private Packet(int opcode, int capacity) {
Opcode = opcode;
buffer = new MemoryStream(capacity);
}
public Packet Write(Object o) {
byte[] b = ObjectToByteArray (o);
buffer.Write (b, 0, b.Length);
return this;
}
private byte[] ObjectToByteArray(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using(MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
}
调用并执行此代码,以向服务器发送包含以下代码的数据包:
public static void Main() {
NetworkClient client = NetworkClient.Create ().Connect ();
Packet packet = Packet.Create (1);
packet.Write ((byte)3);
packet.Write (100L);
packet.Write (100L);
packet.Write (100L);
packet.Write (1840979156127491L);
client.Write (packet);
Console.ReadKey ();
}
这应该写入一个字节(操作码,值为3),然后通过网络写入4个长(Int64)。总大小为33字节
然而,服务器正在读取282字节
执行下面的代码(Java),基本上做同样的事情,读取正确数量的数据(33字节)并正确处理
ByteBuffer buffer = ByteBuffer.allocate(65);
buffer.put((byte) 3); //opcode
buffer.putLong(100L);
buffer.putLong(100L);
buffer.putLong(100L);
buffer.putLong(1840979156127491L);
buffer.flip();
channel.write(buffer);
buffer.compact();
如果有人能帮助我,我将非常感激
# 1 楼答案
当您在代码中调用
packet.Write((byte)3);
时,实际上并没有写入一个字节。相反,它编写一个序列化对象(恰好是一个字节)——实际上,这将是字节本身,加上它周围的几个字节,基本上说“这是一个字节”对于
long
值也是如此为什么不看看
b
方法中包含了什么?数据量将超过你的预期# 2 楼答案
不要使用} 是一条路要走。它允许您在没有任何对象信息的情况下写入数据,因此字节将是字节,整数将是整数,字符串将是一个只编码长度信息的字符串
BinaryFormatter
来写入原始数据^{因此,您可以删除整个
ObjectToByteArray
方法,在创建MemoryStream
时创建一个BinaryWriter
对象,然后只Write()
将数据放入其中。最终,你在MemoryStream
中拥有了你所需要的一切,而且它将比当前创建许多临时对象的方法更加高效