TCP套接字客户端将输出缓慢写入localhos

2024-10-01 11:41:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个应用程序在我的设备上,这是做截图和保存到内存中的位图。将内存中的最后一个位图流到服务器。 每次我的socket客户机将位图的字节写入服务器时,将原始8mb数据发送到127.0.0.1:9090(在本例中是我的python服务器)需要大约400ms的时间。假设它在本地主机上,不是应该更快吗?我需要流尽可能多的帧每秒到我的localhost TCP服务器。我试着在客户端将位图压缩为PNG,但是需要大约1000ms,这就是为什么我不想这样做的原因。我需要原始像素,这样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()


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

基本上,我希望在最短的时间内将尽可能多的数据流传输到localhost服务器,这样就可以获得更多的FPS。对于一个8MB的图像来说,400ms的速度会慢一些。你知道吗


Tags: toinimportself服务器bytesdefmsg
1条回答
网友
1楼 · 发布于 2024-10-01 11:41:04
8355000 Bytes / 0.4 seconds = 20887500 Bytes/second

相当于200兆比特/秒,光纤互联网接入的速度很快,USB连接的速度也很惊人。你知道吗

这个速度还不错。你知道吗

相关问题 更多 >