无法在java(客户端)中的套接字上正确写入数据(类)并在c++;(服务器)

无法在java(客户端)中的套接字上正确写入数据(类)并在c++;(服务器),java,c++,sockets,tcp,Java,C++,Sockets,Tcp,我在这里尝试开发一个客户机-服务器模型。服务器用C++编写,客户端为java。< /强> < /P> 现在,为了获得所需的输出,我在这里做了一些更改。 我尝试了两种方法。 第一种方法如下: Socket socket = new Socket(ip,port); socket.setReuseAddress(true); ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream()); ByteBuf

我在这里尝试开发一个客户机-服务器模型。服务器用C++编写,客户端为java。< /强> < /P> 现在,为了获得所需的输出,我在这里做了一些更改。

我尝试了两种方法。

第一种方法如下:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);
我在ByteBuffer中写入两个整数值,并使用write调用在套接字上发送。代码如下所示:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);

<强>和我已经编写了一个C++套接字代码来接收套接字上的数据包,但是我没有得到想要的数据。下面是我映射传入数据的结构:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);
当我运行我的应用程序时,我得到一些4字节的垃圾值。输出如下:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);
数据包大小:4
t、 a:83946924
t、 b:1836667692

我还使用linux命令tcpdump进行了检查,得到了4个字节。

我尝试过的第二种方法如下:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);
但使用此方法,我收到的是3个数据包,而不是1个。服务器端输出如下:

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new ObjectOutputStream(socket.getOutputStream());

ByteBuffer buffer = ByteBuffer.allocate(8);

buffer.putInt((int)11);
buffer.putInt((int)22);

ostream.write(buffer.array());
struct Test
{
    int a;
    int b;
};
class Test implements Serializable
{
    int a;
    int b;
}

Socket socket = new Socket(ip,port);
socket.setReuseAddress(true);

ObjectOutputStream ostream = new 
ObjectOutputStream(socket.getOutputStream());

Test t = new Test();
t.a = 11;
t.b = 12;

ostream.writeObject(t);
=============================================================
数据包大小:4
t、 a:83946924
t、 b:1836667692
=============================================================
数据包大小:28
t、 a:83915379
t、 b:1953719636
=============================================================
数据包大小:10
t、 a:28792
t、 b:2816

在tcpdump上,我还可以看到有3个数据包,大小分别为4、28和10字节。


<> >强>请大家在这里指导我如何在C++应用程序上发送数据并接收数据,并将其映射到一个结构上。>/P>> P> OK,这里有一些问题。最紧迫的一点是,你不知道你到底在向你的套接字写什么(根据你上面的评论),所以让我们来研究一下

您的
Test
类没有
toString()
方法,因此它默认为输出:

返回对象的字符串表示形式。总的来说 toString方法返回一个字符串,该字符串“以文本形式表示”此 对象结果应该是简洁但信息丰富的表示 这对一个人来说很容易阅读。建议所有 子类重写此方法

类对象的toString方法返回一个字符串,该字符串由 对象作为实例的类的名称,at符号 字符“@”和哈希的无符号十六进制表示形式 对象的代码。换句话说,此方法返回一个等于 价值:

getClass().getName()+'@'+Integer.toHexString(hashCode())

换句话说:不是您想要的两个整数(顺便说一句,一个简单的健全性检查就是通过
println()
抛出这个字符串并检查控制台)

然后,您将其交给执行以下操作的人员:

使用修改的UTF-8将字符串写入基础输出流 以独立于机器的方式编码

首先,将两个字节写入输出流,就像 writeShort方法,提供要跟随的字节数。此值为 实际写入的字节数,而不是 一串在长度之后,输出字符串的每个字符, 按顺序,对字符使用修改的UTF-8编码。如果 不会引发异常,写入的计数器将按 写入输出流的总字节数。这将在 至少两个加上str的长度,最多两个加上str长度的三倍 str的长度

这可以解释为什么会得到两个数据包(长度+字符串),尽管我不知道这是否是实际得到的数据包,因为我不知道“t.a:83946924”是什么意思。也许最好将数据包中的原始数据字节以十六进制格式放入问题中

不管怎样,你现在就是这么做的。作为一个简单的测试,看看是否有更多的错误,或者如果是这样,您可以尝试使用:

将int作为四个字节(高字节)写入底层输出流 第一如果未引发异常,则写入的计数器将递增 到4点

如果顺利通过,应该可以使用tcpdump进行验证


尽管我会响应@sklott的建议去阅读“封送”和“序列化”,因为您可能不想只将原始int写入流。添加一些标题信息或其他“传输开始”信息将是一个好主意-您也可以在末尾添加一些CRC或其他内容,但因为您使用的是TCP,所以这应该不是必需的。

您知道
writeUTF
toString
在Java中做什么吗?不完全知道,但据我所知,writeUTF,它接受字符串形式的参数。所以我已经使用ToScRin你的C++代码在哪里?您是否使用wireshark检查Java代码是否发送了您期望的数据?请注意,Java中
toString
的默认实现返回了对象的类名和哈希代码,这不是您想要的“我不知道writeUTF做什么,但它写了一些东西,我知道它需要一个字符串,所以我称之为toString”-通过尝试和错误进行编程通常不起作用-你必须知道程序实际上做了什么,而不是把碰巧合适的东西放在一起。谢谢你的时间。但是我不能使用writeInt函数,因为我想一次写入整个对象。