【发布时间】:2016-08-20 17:10:12
【问题描述】:
我使用Socket 发送位图,其中客户端是我的.apk,服务器是Delphi 可执行文件。
位图发送成功,但在服务器上接收时,Bitmap 为空,大小为 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());
}
}
【问题讨论】:
-
再一次,你没有花时间描述你的代码应该做什么和真正做什么。您只是在倾倒大量代码。已经是第三次了。
-
I'm sending a Bitmap using Socket。不。您正在发送字节数组的len字节。您用位图中的像素填充了字节数组。在服务器端,您应该收到len字节。现在你在服务器上收到了什么?您抱怨位图的大小为 0。但位图仅在之后从接收到的字节构造,所以起初无关紧要。现在准确地告诉你发送了多少字节,你收到了多少。从一些基本的调试开始。 -
@greenapps,在服务器端:
Socket.ReceiveLength接收大小为 4。` -
我看到您上次询问时仍未接受我的批评意见。这甚至不是建议。当您连接多个客户端时,您的 Delphi 代码将不起作用。而你甚至给混乱添上了更多东西。
标签: java android sockets delphi