gpt4 book ai didi

java - Android 通过套接字发送图像,但在服务器端始终接收到空

转载 作者:行者123 更新时间:2023-12-02 03:25:03 25 4
gpt4 key购买 nike

我使用 Socket 发送位图,其中客户端是我的 .apk,服务器是 Delphi 可执行文件。

位图发送成功,但服务器接收时,位图为空,大小为0KB。

所以,如果可能的话,我想要任何建议或解决方案,以解决这个问题。

到目前为止,这是我的代码:

Android(客户端)

public class MainActivity extends Activity {

Socket clientSocket;

private static final int SERVERPORT = 60;
private static final String SERVER_IP = "192.168.25.227";

byte[] tmpbytes = null;


@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

new Thread(new ClientThread()).start();

}

public Bitmap takeScreenshot() {

View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();

}

public void getBytes() throws IOException {

try
{

Bitmap bmp = takeScreenshot();

int bytes = bmp.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bmp.copyPixelsToBuffer(buffer);

byte[] array = buffer.array();
int start=0;
int len=array.length;
if (len < 0)
throw new IllegalArgumentException("Negative length not allowed");
if (start < 0 || start >= array.length)
throw new IndexOutOfBoundsException("Out of bounds: " + start);

OutputStream out = clientSocket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);

dos.writeInt(len);
if (len > 0) {
dos.write(array, start, len);
}



}

catch (UnknownHostException e) {
//System.out.println(e.toString());
}

catch (IOException e) {
//System.out.println(e.toString());
}

catch (Exception e1) {
//Log.e("clients", e1.toString());
//Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
System.out.println(e1.toString());
}

}

class ClientThread implements Runnable {

@Override
public void run() {

try {

InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

clientSocket = new Socket(serverAddr, SERVERPORT);

//new Thread(new CommsThread()).start();

Thread.sleep(1000);

getBytes();

} catch (Exception e1) {
//Log.e("clients", e1.toString());
//Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
System.out.println(e1.toString());
}

}
}

}

Delphi(服务器)

var
Form1: TForm1;

stSize: integer;
Stream: TMemoryStream;
bmp: TBitmap;
FSize: Integer;
writing: Boolean;

procedure TForm1.FormCreate(Sender: TObject);
begin
Stream:= TMemoryStream.Create;
writing:= False;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
BytesReceived: Longint;
CopyBuffer: Pointer; { buffer for copying }
ChunkSize: Integer;
TempSize: Integer;
const
MaxChunkSize: Longint = 8192; { copy in 8K chunks }
begin

If FSize=0 then
begin
If Socket.ReceiveLength>SizeOf(TempSize) then
begin
Socket.ReceiveBuf(TempSize,SizeOf(TempSize));
Stream.SetSize(TempSize);
FSize:= TempSize //Threadsafe code!
End;
End;

If (FSize>0) and not(writing) then
begin
GetMem(CopyBuffer, MaxChunkSize); { allocate the buffer }
writing:= True;
While Socket.ReceiveLength>0 do
Begin
ChunkSize:= Socket.ReceiveLength;
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
BytesReceived:= Socket.ReceiveBuf(CopyBuffer^,ChunkSize);
Stream.Write(CopyBuffer^, BytesReceived); { ...write chunk }
Dec(FSize,BytesReceived);
End;
end;

If FSize=0 then begin

Stream.Position := 0;
bmp:=TBitmap.Create;
bmp.LoadFromStream(Stream);
Image1.Picture.Graphic := bmp;
Stream.SetSize(0);
bmp.Free;
FSize:= 0;
end;

FreeMem(CopyBuffer, MaxChunkSize); { allocate the buffer }
Writing:= False;
end;

:

经过 Remy Lebeau 的建议,我所做的更改仍然不起作用:-(

德尔福

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
BytesReceived: Longint;
CopyBuffer: Pointer;
ChunkSize: Integer;
TempSize: Integer;
const
MaxChunkSize: Longint = 8192;
begin

If FSize=0 then
begin
If Socket.ReceiveLength>SizeOf(TempSize) then
begin
Socket.ReceiveBuf(TempSize,SizeOf(TempSize));
TempSize := ntohl(TempSize); // Changed to ntohl
Stream.SetSize(TempSize);
FSize:= TempSize
End;
End;

If (FSize>0) and not(writing) then
begin
GetMem(CopyBuffer, MaxChunkSize);
writing:= True;
While Socket.ReceiveLength>0 do
Begin
ChunkSize:= Socket.ReceiveLength;
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
BytesReceived:= Socket.ReceiveBuf(CopyBuffer^,ChunkSize);
Stream.Write(CopyBuffer^, BytesReceived);
Dec(FSize,BytesReceived);
End;
end;

If FSize=0 then begin

Stream.Position := 0;
png:=TPngImage.Create; // Changed to TPNGImage here
png.LoadFromStream(Stream);
Image1.Picture.Assing(png);
Stream.SetSize(0);
png.Free;
FSize:= 0;
end;

FreeMem(CopyBuffer, MaxChunkSize);
Writing:= False;
end;

Android

public void getBytes() throws IOException {

try
{

Bitmap bmp = takeScreenshot();

ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] array = bos.toByteArray();
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(array.length);
dos.write(array, 0, array.length);

}

catch (UnknownHostException e) {
//System.out.println(e.toString());
}

catch (IOException e) {
//System.out.println(e.toString());
}

catch (Exception e1) {
//Log.e("clients", e1.toString());
//Toast.makeText(MainActivity.this, e1.toString(), Toast.LENGTH_LONG).show();
System.out.println(e1.toString());
}

}

最佳答案

您的代码存在很多问题。

您没有关注ReceiveBuf()的返回值。它返回实际读取的字节数,该字节数可能比您请求的字节数少,或者在断开连接时返回 0,或在出错时返回 -1(尤其是在非阻塞模式下使用服务器时)。你需要处理这些情况。您需要循环读取 TempSize 。当您恰好收到 FSize 时,您需要停止循环。读取像素时的字节数。

您没有考虑字节序。 DataOutputStream.writeInt()大端字节顺序写入整数字节。 Windows 上的 Delphi 是小端。您调用ReceiveBuf(TempSize,SizeOf(TempSize))正在按原样读取整数字节,因此 TempSize将采用大尾数法。在使用之前,您需要将值转换为小端字节序。您可以使用ntohl()为此:

TempSize := ntohl(TempSize);

您的客户端仅发送原始像素数据,但是 TBitmap.LoadFrom...()需要完整的.bmp文件,包括BITMAPFILEHEADERBITMAPINFOHEADER描述位图及其像素的 header (请参阅 Bitmap Storage )。您需要发送这些 header ,或者至少填充您的 Stream在将像素读入其中之前先使用它们。

但是,Android 对 bmp 没有很好的支持格式,所以你最好使用 Bitmap.compress()将位图数据提取为 PNG,然后使用 TPNGImage在 Delphi 端加载它。

关于java - Android 通过套接字发送图像,但在服务器端始终接收到空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39056751/

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