gpt4 book ai didi

java - TCP 套接字客户端将输出写入本地主机的速度很慢

转载 作者:行者123 更新时间:2023-12-02 09:27:55 24 4
gpt4 key购买 nike

我的设备上有一个应用程序,它可以进行屏幕截图并将位图保存到内存中。将内存中的最后一个位图流式传输到服务器。每次我的套接字客户端将位图的字节写入服务器时,将原始 8 MB 数据发送到 127.0.0.1:9090(在本例中是我的 python 服务器)大约需要 400 毫秒。假设它在本地主机上,它不是应该更快吗?我需要每秒将尽可能多的帧传输到本地主机 TCP 服务器。我尝试在客户端将位图压缩为 PNG,但需要大约 1000 毫秒,这就是我不想这样做的原因。我需要原始像素,因此 JPEG 也无法工作,因为它是有损压缩。

OutputStream.write()的执行时间:

OutputStream wrote 8355840 bytes to localhoost in 414ms
OutputStream wrote 8355840 bytes to localhoost in 386ms
OutputStream wrote 8355840 bytes to localhoost in 475ms
OutputStream wrote 8355840 bytes to localhoost in 413ms
OutputStream wrote 8355840 bytes to localhoost in 409ms
OutputStream wrote 8355840 bytes to localhoost in 394ms
OutputStream wrote 8355840 bytes to localhoost in 463ms
OutputStream wrote 8355840 bytes to localhoost in 411ms
OutputStream wrote 8355840 bytes to localhoost in 434ms
OutputStream wrote 8355840 bytes to localhoost in 407ms
OutputStream wrote 8355840 bytes to localhoost in 403ms
OutputStream wrote 8355840 bytes to localhoost in 478ms
OutputStream wrote 8355840 bytes to localhoost in 434ms
OutputStream wrote 8355840 bytes to localhoost in 417ms
package com.genymobile.scrcpy;

import android.graphics.Bitmap;
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;

public final class Main {
static Bitmap mFrame = null;

public static void main(String... args) {
new Thread(new Client()).start();
while(true) {
mFrame = ScreenCaptorUtils.screenshot(1080, 1920);
}
}

private static class Client implements Runnable {
public void run() {
try {
Socket socket = new Socket("127.0.0.1", 9090);
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
while(mFrame == null) {
Thread.sleep(100);
}
while(true) {
ByteBuffer buffer = ByteBuffer.allocate(mFrame.getByteCount());
mFrame.copyPixelsToBuffer(buffer);
byte[] frameBytes = buffer.array();
out.write(ByteBuffer.allocate(4).putInt(frameBytes.length).array()); // Write header - 4 bytes integer with the bitmap size
long start = System.currentTimeMillis();
out.write(frameBytes); // Write raw bitmap bytes
System.out.println("OutputStream wrote " + String.valueOf(frameBytes.length) + " bytes to localhoost in " + String.valueOf(System.currentTimeMillis() - start) + "ms");
}
} catch(Exception e) { e.printStackTrace(); }
}
}
}

设备通过 USB 连接,WIFI 已禁用。我使用以下命令打开 9090 端口:

adb reverse tcp:9090 tcp:9090

这也是 python 服务器:

import socket
import sys
import time
from threading import Thread
from struct import *
from io import BytesIO
from PIL import Image

class BitmapStreamSocket:
LAST_FRAME = None

def __init__(self, host, port):
self.host = host
self.port = port
self.last_frame = None
self.start_server()

def client_thread(self, sock):
print("Client thread started")
while True:
barr = self.recv_msg(sock)
if barr:
stream = BytesIO(bytes(barr))
print("Just got ", len(barr), "bytes: ", time.time())
else:
print("Client just disconnected")
return

def send_msg(self, sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = pack('>I', len(msg)) + msg
sock.sendall(msg)

def recv_msg(self, sock):
# Read message length and unpack it into an integer
raw_msglen = self.recvall(sock, 4)
if not raw_msglen:
return None
msglen = unpack('>I', raw_msglen)[0]
# Read the message data
recvall = self.recvall(sock, msglen)
return recvall

def recvall(self, sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data

def start_server(self):
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire
try:
soc.bind((self.host, self.port))
except:
print("Bind failed. Error : " + str(sys.exc_info()))
sys.exit()
soc.listen(5) # queue up to 5 requests
print("Socket now listening")

# infinite loop- do not reset for every requests
while True:
connection, address = soc.accept()
print("Connected with " + str(address[0]) + ":" + str(address[1]))
t = Thread(target=self.client_thread, args=(connection,))
t.start()
soc.close()


客户端没有从服务器接收输入,因为服务器没有发送任何输入。客户端只发送数据,服务器接收数据。

基本上,我想在最短的时间内将尽可能多的数据传输到本地主机服务器,这样我就可以获得更高的 FPS。一张 8 MB 图像需要 400 毫秒,这样就太慢了。

最佳答案

8355000 Bytes / 0.4 seconds = 20887500 Bytes/second

相当于大约 200 MBit/秒,对于光纤互联网接入来说是一个不错的速度,对于 USB 连接来说也是惊人的。

这个速度还不错。

关于java - TCP 套接字客户端将输出写入本地主机的速度很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58205348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com