【问题标题】:Reusing sockets in server-client在服务器-客户端重用套接字
【发布时间】:2015-12-08 15:35:55
【问题描述】:

我正在尝试创建一个客户端-服务器系统:我的服务器是一个树莓派,它在上面运行一个 python 网络服务器,而我的客户端在另一台电脑上并且是用 Java 编写的。这个想法是服务器收集数据,当它收到来自客户端的请求时,它将数据发送给客户端。 我的客户应该请求数据,等待 10 秒然后再次请求等等。

目前这个系统正在工作,但是大约一天后,客户端开始收到很多(但不是连续的)套接字超时。我认为可能是这种情况,因为对于每个请求,我都会创建一个新的套接字进行通信,并且我认为一天后套接字会用完或类似的东西。这是客户端每 10 秒执行一次的代码:

    public static String getData() throws Exception {
    TreeSet<Integer> primes = MathUtils.primesSieve(10000);
    try {
        String data = "";
        Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
        socket.setReuseAddress(true);
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        int msg = ColUtils.drawRandomlyWithReplacement(primes, 1, ArrayList::new).get(0);
        out.write(msg+"");
        out.flush();
        String input;
        while ((input = in.readLine()) != null) {
            data += input;
            if (!data.endsWith("#" + prod(msg))) {
                throw new Exception("WRONG ECHO");
            }
        }
        socket.close();

        return data;
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

我尝试通过拥有一个作为封装类成员的套接字来修复它,但是在单个请求之后,输入流停止工作。有什么方法可以让我继续使用单个套接字与服务器进行所有通信?或者这是进行这种交流的推荐方式?

【问题讨论】:

  • 当你 close() 套接字时,它的所有资源都将被释放,所以你不能在那里“用尽套接字”。只要确保你close()套接字在任何情况下,即使发生异常:try { ... } finally { socket.close(); }
  • 服务器/Python 端会不会有问题?
  • 感谢您的建议,我会尝试并回复您。我认为服务器端没有问题:当我得到所有超时时,只需重新启动客户端即可解决问题。
  • 顺便说一句,setReuseAddress()meaningful for ServerSockets only
  • @HannoBinder 这在这段代码中肯定没有意义,因为Socket 已经在构造中绑定和连接了。

标签: java sockets


【解决方案1】:

尝试先关闭套接字和输入、输出流。与您的代码一样,无法保证您正在释放获取的对象。

PrintWriter out = null;
BufferedReader in = null;
Socket socket = null;
try {
  ...//your statements
} catch (Exception ex) {
  //catch or whatever
} finally {
  if (out != null) out.close();
  if (in != null) in.close();
  if (socket != null) socket.close();
}

【讨论】:

  • 所以使用这种方法应该可以避免我在运行一天/几天后遇到套接字超时?
  • 无法确定。但是显式关闭套接字绝对是一件坏事。
  • 每个套接字连接都应该使用一些 tcp 端口进行连接,并且它使用允许范围内的第一个未使用的端口,我假设由于您的代码没有正确释放服务器已经使用的所有可能的资源连接,所以这可能会有所帮助。
  • @HéctorvandenBoorn 进展如何?从昨天开始还有超时吗? :)
【解决方案2】:

尝试使 Socket 对象静态如果可能的话,只创建一次并每 10 秒读取一次数据 否则你可以在调用 getData 方法之前实例化它然后读取它。 这样做只会制作 1 个 Socket 副本。

而且我不认为你的端口用完了。 原因可能很简单,因为您的程序在超时之前没有接收到数据。在网络不好的情况下是正常情况

如果没有以编程方式设置超时,Socket 一般会无限期等待直到收到数据

【讨论】:

    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2011-08-15
    • 2017-05-26
    相关资源
    最近更新 更多