Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
调整Java的性能';s形插座_Java_Performance_Sockets_Networking - Fatal编程技术网

调整Java的性能';s形插座

调整Java的性能';s形插座,java,performance,sockets,networking,Java,Performance,Sockets,Networking,我已经创建了一个远程桌面控制应用程序。显然,它由客户端和服务器部分组成: 服务器: ServerSocket serverSocket = new ServerSocket(); serverSocket.setReceiveBufferSize( ? ); // #1 serverSocket.bind(new InetSocketAddress(...)); Socket clientSocket = serverSocket.accept(); c

我已经创建了一个远程桌面控制应用程序。显然,它由客户端和服务器部分组成:

服务器:

    ServerSocket serverSocket = new ServerSocket();
    serverSocket.setReceiveBufferSize( ? ); // #1
    serverSocket.bind(new InetSocketAddress(...));

    Socket clientSocket = serverSocket.accept();
    clientSocket.setSendBufferSize( ? ); // #2
    clientSocket.setReceiveBufferSize( ? ); // #3

    OutputStream outputStream = new BufferedOutputStream(
            clientSocket.getOutputStream(), ? ); // #4
    InputStream inputStream = new BufferedInputStream(
            clientSocket.getInputStream(), ? ); // #5
    Socket socket = new Socket(...);
    socket.setSendBufferSize( ? ); // #6
    socket.setReceiveBufferSize( ? ); // #7

    OutputStream outputStream = new BufferedOutputStream(
            socket.getOutputStream(), ? ); // #8
    InputStream inputStream = new BufferedInputStream(
            socket.getInputStream(), ? ); // #9
  • 从客户端接收鼠标/键盘操作
  • 正在将桌面截图发送到客户端
客户端:

    ServerSocket serverSocket = new ServerSocket();
    serverSocket.setReceiveBufferSize( ? ); // #1
    serverSocket.bind(new InetSocketAddress(...));

    Socket clientSocket = serverSocket.accept();
    clientSocket.setSendBufferSize( ? ); // #2
    clientSocket.setReceiveBufferSize( ? ); // #3

    OutputStream outputStream = new BufferedOutputStream(
            clientSocket.getOutputStream(), ? ); // #4
    InputStream inputStream = new BufferedInputStream(
            clientSocket.getInputStream(), ? ); // #5
    Socket socket = new Socket(...);
    socket.setSendBufferSize( ? ); // #6
    socket.setReceiveBufferSize( ? ); // #7

    OutputStream outputStream = new BufferedOutputStream(
            socket.getOutputStream(), ? ); // #8
    InputStream inputStream = new BufferedInputStream(
            socket.getInputStream(), ? ); // #9
  • 从服务器接收屏幕截图
  • 发送鼠标/键盘操作
考虑发送屏幕截图。当我将家用电脑用作服务器时,我最终得到的屏幕截图尺寸为1920x1080。通过使用PNG并将其编码为PNG,我能够为如此大的图像获得以下统计信息:

  • 写入时间~0.2秒;(不是进入套接字,而是进入一些“常规”输出流,即编码时间
  • 读取时间~0.05秒;(不是来自套接字,而是来自一些“常规”输入流,即解码时间)
  • 大小约250 KB
  • 完美的品质
  • 因此,根据#1-理想的可能FPS应为~5

    不幸的是,我甚至不能达到~5 FPS,甚至不能达到2 FPS。我搜索了瓶颈,发现对套接字I/O流的写入/读取要花费~2秒(请参见附录1和附录2以了解详情)。这当然是不能接受的

    我稍微研究了一下这个主题,并在两侧添加了套接字I/O流的缓冲(使用
    BufferedInputStream
    BufferedOutputStream
    )。我从64KB大小开始。这确实提高了性能。但仍然不能有至少2 FPS!此外,我还对
    Socket#setReceiveBufferSize
    Socket#setEndBufferSize
    进行了实验,在速度上有一些变化,但我不知道它们的具体行为,因此我不知道使用哪些值

    请看初始化代码:

    服务器:

        ServerSocket serverSocket = new ServerSocket();
        serverSocket.setReceiveBufferSize( ? ); // #1
        serverSocket.bind(new InetSocketAddress(...));
    
        Socket clientSocket = serverSocket.accept();
        clientSocket.setSendBufferSize( ? ); // #2
        clientSocket.setReceiveBufferSize( ? ); // #3
    
        OutputStream outputStream = new BufferedOutputStream(
                clientSocket.getOutputStream(), ? ); // #4
        InputStream inputStream = new BufferedInputStream(
                clientSocket.getInputStream(), ? ); // #5
    
        Socket socket = new Socket(...);
        socket.setSendBufferSize( ? ); // #6
        socket.setReceiveBufferSize( ? ); // #7
    
        OutputStream outputStream = new BufferedOutputStream(
                socket.getOutputStream(), ? ); // #8
        InputStream inputStream = new BufferedInputStream(
                socket.getInputStream(), ? ); // #9
    
    客户端:

        ServerSocket serverSocket = new ServerSocket();
        serverSocket.setReceiveBufferSize( ? ); // #1
        serverSocket.bind(new InetSocketAddress(...));
    
        Socket clientSocket = serverSocket.accept();
        clientSocket.setSendBufferSize( ? ); // #2
        clientSocket.setReceiveBufferSize( ? ); // #3
    
        OutputStream outputStream = new BufferedOutputStream(
                clientSocket.getOutputStream(), ? ); // #4
        InputStream inputStream = new BufferedInputStream(
                clientSocket.getInputStream(), ? ); // #5
    
        Socket socket = new Socket(...);
        socket.setSendBufferSize( ? ); // #6
        socket.setReceiveBufferSize( ? ); // #7
    
        OutputStream outputStream = new BufferedOutputStream(
                socket.getOutputStream(), ? ); // #8
        InputStream inputStream = new BufferedInputStream(
                socket.getInputStream(), ? ); // #9
    
    问题:

        ServerSocket serverSocket = new ServerSocket();
        serverSocket.setReceiveBufferSize( ? ); // #1
        serverSocket.bind(new InetSocketAddress(...));
    
        Socket clientSocket = serverSocket.accept();
        clientSocket.setSendBufferSize( ? ); // #2
        clientSocket.setReceiveBufferSize( ? ); // #3
    
        OutputStream outputStream = new BufferedOutputStream(
                clientSocket.getOutputStream(), ? ); // #4
        InputStream inputStream = new BufferedInputStream(
                clientSocket.getInputStream(), ? ); // #5
    
        Socket socket = new Socket(...);
        socket.setSendBufferSize( ? ); // #6
        socket.setReceiveBufferSize( ? ); // #7
    
        OutputStream outputStream = new BufferedOutputStream(
                socket.getOutputStream(), ? ); // #8
        InputStream inputStream = new BufferedInputStream(
                socket.getInputStream(), ? ); // #9
    
  • 您会为所有人推荐哪些值(以提高性能) 这些案例以及原因
  • 请澄清
    Socket#setReceiveBufferSize
    Socket#setSendBufferSize
    行为
  • 您可以建议哪些其他方法/技巧来提高性能 这种应用有什么意义
  • Skype提供高质量的实时桌面传输-他们是如何做到的
  • 附录1:添加客户端套接字读取的展开伪代码(@mcfinnigan):

    while(true){
    //objectInputStream是包装套接字的缓冲输入流。
    
    Object Object=objectInputStream.readObject();//你可以看看Java NIO(),使用多个频道,等等。

    我认为最大的浪费在于桌面的完全传输。你应该把它当作电影,对帧进行差异编码

    缺点是处理更复杂。也许有一些简单的视频编解码器API/实现

    • 写入时间~0.2秒
    • 读取时间~0.05秒
    如果不考虑介入网络的延迟和带宽,这些目标是完全没有意义的

    大小约250 KB

    离题。图片大小由你决定,与实际编程无关,这是本网站的目的

    完美的品质

    “完美质量”只要求您不丢弃任何位,而这些位无论如何都不会通过TCP获得

      serverSocket.setReceiveBufferSize( ? ); // #1
    
    这将为所有接受的套接字设置接收缓冲区大小。将其设置为您能承受的最大值,如果可能,超过64k

    socket.setSendBufferSize( ? ); // #6
    
    尽可能将其设置为最大值,如果可能,超过64k

        socket.setReceiveBufferSize( ? ); // #7
    
    由于这是一个可接受的套接字,您已在上面执行了此操作。请删除

        OutputStream outputStream = new BufferedOutputStream(
                socket.getOutputStream(), ? ); // #8
        InputStream inputStream = new BufferedInputStream(
                socket.getInputStream(), ? ); // #9
    
    这些的默认值是8k;只要您有合适的套接字缓冲区大小就足够了

    对于所有这些情况,您会推荐哪些值(以提高性能),为什么

    见上文

    请澄清
    Socket#setReceiveBufferSize()
    Socket#setSendBufferSize()
    行为

    它们控制TCP“窗口”的大小。这是一个相当深奥的主题,但其思想是使大小至少等于网络的带宽延迟乘积,即带宽(字节/秒)乘以延迟(秒)>=缓冲区大小(字节)

    您可以建议哪些其他方法/技术来提高此类应用程序的性能

    发送数据时,不要在睡觉和做其他任务的时候胡闹。尽可能快地发送数据,并尽可能紧密地循环发送

    Skype提供高质量的实时桌面传输-他们是如何做到的

    离题,可能不可知,除非Skype员工碰巧想在这里泄露公司机密。

    • 如果客户端为每个映像打开新的TCP连接,则可能会导致缓慢。-->对所有帧使用相同的TCP连接

    • TCP有自己的缓冲区,这些缓冲区是TCP的最佳使用方式-->
      BufferedOutputStream
      有时会带来好处,有时则不会

    • 通常在截图之间只更改屏幕的一小部分。-->仅传输更改的部分

      • 问题很清楚。 我上面的人建议使用多个nio通道,我宁愿使用多个阻塞套接字(nio不是更快)。然而,这并没有改善网络通信,这是并行编程,在您的情况下肯定是一个很好的解决方案。 让我提出以下建议


        如果将其设置为true,您将能够以增加带宽消耗为代价加快套接字通信速度。

        您确定套接字设置是您的限制因素吗?您的客户端和服务器之间有什么样的连接?服务器的加速速度是多少?您能将从套接字读取的代码发布到服务器上吗客户端?@Roger Lindsjö你所说的“什么样的连接”是什么意思?我怎样才能衡量连接的速度