首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从socket流读取时Genson的行为非常奇怪

从socket流读取时Genson的行为非常奇怪
EN

Stack Overflow用户
提问于 2018-12-11 06:43:40
回答 2查看 56关注 0票数 1

我试图使用Genson库在服务器和客户端之间执行通信。我检测到了以下问题:当服务器上的genson试图读取消息时,我的应用程序试图向服务器发送消息。

同时,如果我关闭客户端,消息将被完美地读取和处理。我认为这是僵局,但不确定。

本机Java序列化没有这样的问题。

这是我的服务器:

代码语言:javascript
复制
import com.owlike.genson.Genson;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

public class Server {
    public static void main(String[] args) throws IOException {
        Genson genson = new Genson();

        try (ServerSocket server = new ServerSocket(9991)) {
            try (Socket socket = server.accept()) {
                int[] loc = genson.deserialize(socket.getInputStream(), int[].class);
                System.out.println("Server: " + Arrays.toString(loc));
                genson.serialize(loc, socket.getOutputStream());
            }
        }
    }
}

这是客户端:

代码语言:javascript
复制
import com.owlike.genson.Genson;

import java.io.IOException;
import java.net.Socket;
import java.util.Arrays;

public class Client {
    public static void main(String[] args) throws IOException {
        Genson genson = new Genson();

        try (Socket socket = new Socket("localhost", 9991)) {
            genson.serialize(new int[] {1, 2, 3}, socket.getOutputStream());
            int[] loc = genson.deserialize(socket.getInputStream(), int[].class);
            System.out.println("Client: " + Arrays.toString(loc));
        }
    }
}

我非常感谢对这个问题的任何帮助。提前谢谢。

编辑:这真是太棒了。我做了一些额外的测试,下面是我得到的结果:

附加课程:

代码语言:javascript
复制
import com.owlike.genson.annotation.JsonProperty;

import java.io.Serializable;

public class Tester implements Serializable {
    public static final Tester TEST = new Tester(Math.E);

    private double val = Math.PI;

    public Tester(@JsonProperty("val") double val) {
        this.val = val;
    }

    public Tester() {}

    public String toString() {
        return "" + val;
    }
}

在客户端请求中编写了genson.serialize(Tester.TEST, socket.getOutputStream())之后,我得到了相同的奇怪结果。但是写了genson.serialize(new Tester(Double.NaN), socket.getOutputStream()),结果就是被删掉的结果。

此外,如果我将Tester类中唯一的字段定义为int[]类型,那么假设它只适用于nullnew int[0]的值。

此外,如果我试图序列化和传输0.9范围内整数的int,我会观察到以下行为:除了当我关闭客户机时,服务器总是显示0值。

此外,对于Double.NaNDouble.POSITIVE_INFINITYInteger.MAX_VALUE等常量,根本没有什么奇怪的地方(一切都如预期的那样工作)。

对于这些附加测试,Genson类的定义如下:

代码语言:javascript
复制
Genson genson = new GensonBuilder()
        .useMethods(false)
        .setFieldFilter(VisibilityFilter.PRIVATE)
        .create();

注意到,当ser/deser使用流访问/从文件发送时没有这样的问题:

代码语言:javascript
复制
import com.owlike.genson.Genson;
import com.owlike.genson.GensonBuilder;
import com.owlike.genson.reflect.VisibilityFilter;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileTest {
    private static final String FILENAME = "test.json";

    public static void main(String[] args) throws IOException {
        Genson genson = new GensonBuilder()
                .useMethods(false)
                .setFieldFilter(VisibilityFilter.PRIVATE)
                .useIndentation(true)
                .create();

        try (OutputStream stream = new FileOutputStream(FILENAME)) {
            genson.serialize(Tester.TEST, stream);
        }

        try (InputStream stream = new FileInputStream(FILENAME)) {
            System.out.println(genson.deserialize(stream, Tester.class));
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-25 03:34:48

读取API中的一些代码路径将尝试确保至少有N个字节可用,或者已经到达EOF。正如您所提到的,在解析一个数字(这不是常量)时,总是会发生这种情况。

一个选项可以是实现一个小层,该层序列化为字节数组或字符串,获取消息长度并将其写入输出,然后是有效负载。在读取端,您将首先读取长度,然后在while循环中从流中读取,直到达到该长度或EOF为止。

然后,您只需在内存消息中传递给Genson.deseralize。

票数 0
EN

Stack Overflow用户

发布于 2018-12-11 21:14:47

好像一直都是我的错。我忘记了套接字的流不能关闭(除非您也想关闭套接字)。因此,在这种情况下,Server尝试从InputStream获取尽可能多的数据,但它不能消耗所有的流(因为它总是打开的,数据可以随时从客户端发送)。因此,Server基本上冻结等待数据,但没有更多的数据来。因此,我们有上述情况。

一个解决方案是指定某种协议来表示查询大小,这样Server就可以知道它应该消耗多少数据。有关更多细节,请参见this答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53718743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档