【问题标题】:Java Socket waiting for UTF8Java Socket 等待 UTF8
【发布时间】:2015-04-27 13:10:46
【问题描述】:

我正在尝试自己实现一个客户端-服务器应用程序。到目前为止,它的工作原理是,当我通过另一个应用程序(例如 Web 浏览器)访问端口时,服务器应用程序被阻塞。

如果连接的应用程序是“客户端应用程序”,是否有任何简单的方法/良好做法来检查?

这是一个监听端口 8080 的套接字的简短示例。套接字等待 2 个字符串。如果您现在使用浏览器 (localhost:8080) 连接,则连接已建立,但正在等待第一个 UTF8。

public class MainSocket {

public static void main(String[] args) {
    ServerSocket serverSocket;
    try {            
        serverSocket = new ServerSocket(8080);
        while (true) {
            try {
                Socket clientSocket = serverSocket.accept();
                System.out.println("Connection established");
                DataInputStream in = new DataInputStream(clientSocket.getInputStream());
                System.out.println(in.readUTF());
                System.out.println(in.readUTF());
                in.close();
                clientSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

【问题讨论】:

  • DataInputStream 设计用于读取 binary 数据,而不是文本。我建议使用众多 Reader 实现中的一种来阅读文本。

标签: java sockets


【解决方案1】:

你打电话给DataInputStream.readUTF8。这需要这样的数据:

首先,读取两个字节并使用 readUnsignedShort 方法的方式构造一个无符号的 16 位整数。这个整数值称为 UTF 长度,并指定要读取的附加字节数。然后通过分组考虑将这些字节转换为字符。每个组的长度是根据组的第一个字节的值计算的。组后面的字节(如果有)是下一组的第一个字节。

(等)

换句话说,这不仅仅是 UTF-8。这是对带有长度前缀的 UTF-8 的细微变化。这不是浏览器要写入连接的内容。基本上,DataInputDataOutput 是对称的,但并不完全是通用的——它们通常一起使用,一边通过 DataInput 读取另一边用 DataOutput 写的内容。

如果你只想读取 UTF-8 的行,你可以使用:

try (Reader inputReader = new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8);
    BufferedReader reader = new BufferedReader(inputReader)) {
    System.out.println(read.readLine());
    System.out.println(read.readLine());
}

(现在还不清楚您是否应该期望浏览器将 UTF-8 写入套接字,但以上内容更有可能让您进入下一步,我想说...)

【讨论】:

  • 感谢您的回答。这正是我面临的问题。从我的客户端应用程序中,我将 2*UTF 和 1*File 写入服务器。但是现在,如果我通过浏览器访问服务器的端口,服务器正在阻塞,因为它正在等待第一个 readUTF。
  • @AndreasFreitag:是的——如果您的客户端应用程序和浏览器要发出不同的请求,您为什么要尝试在同一个端口上处理它们?
  • 他们使用不同的端口,但如果用户访问 8080 端口,则服务器被阻止。在真正的服务器应用程序中,我使用的是一个有 10 个套接字的套接字池,所以这不是什么大问题。但在我看来,这不是一个好习惯。
  • @AndreasFreitag:听起来这个问题更像是一个线程问题——要么使用异步 IO,要么为每个连接使用不同的线程。
  • 所以实现一些描述的超时——这很烦人,但应该不会太糟糕。如果任何请求花费的时间过长,请关闭与该请求关联的套接字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 1970-01-01
  • 2012-06-06
  • 2016-04-28
  • 2021-07-01
相关资源
最近更新 更多