You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreadBlocking模式下Delphi服务端与Android客户端Socket连接问题咨询

Android Socket无法连接Delphi ThreadBlocking模式TServerSocket的问题排查与修复

Hey there, let's tackle this connection issue between your Android client and Delphi server. First off, Android's Socket operates in blocking mode by default—you don't need to explicitly set anything for that. The problem is likely elsewhere in your code or configuration. Let's break down the key issues and fixes:

一、先排查基础连接障碍

Before diving into code, rule out these common environment issues:

  • Firewall/Network: Make sure the Delphi server's port (60) is open in its firewall, and both devices are on the same local network (your 192.168.15.13 IP looks like a local LAN address, which is good).
  • Android Permissions: Ensure your AndroidManifest.xml includes:
    <uses-permission android:name="android.permission.INTERNET"/>
    
    For Android 9+, you also need to allow cleartext traffic (since plain Socket connections are considered cleartext):
    <application
        ...
        android:usesCleartextTraffic="true">
    
  • Port Consistency: Double-check that Delphi's ServerSocket1.Port is indeed set to 60, matching your Android client's SERVERPORT.

二、Android端代码的关键问题

Your Android client has several stream-handling mistakes that could break connection or communication:

1. Repeatedly creating stream wrappers inside the loop

In your CommsThread.run() method, you create BufferedReader, PrintWriter, and later DataOutputStream inside the while loop. This is bad practice—repeatedly wrapping the same Socket stream causes buffer conflicts and unexpected behavior. Create these streams once before the loop:

class CommsThread implements Runnable {
    @Override
    public void run() {
        try {
            System.out.println("Waiting for server request");
            // Create streams ONCE outside the loop
            BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())), true);
            DataOutputStream dos = new DataOutputStream(clientSocket.getOutputStream());
            
            String line;
            // Remove clientSocket.isConnected() check—readLine() will block until data or disconnect
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
                if(line != null && !line.trim().isEmpty()) {
                    if(line.equalsIgnoreCase("screencapture")){
                        // Take screenshot with MediaProjection api
                        // Send to server
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
                        byte[] array = bos.toByteArray();
                        dos.writeInt(array.length);
                        dos.write(array, 0, array.length);
                        dos.flush();
                    }
                    if(line.equalsIgnoreCase("exit")) {
                        break;
                    }
                }
            }
            System.out.println("Shutting down Socket!!");
            // Close all streams and socket properly
            reader.close();
            out.close();
            dos.close();
            clientSocket.close();
        } catch (Exception e1) {
            System.out.println(e1.toString());
            // Add cleanup in catch block to avoid resource leaks
            try {
                if(clientSocket != null) clientSocket.close();
            } catch(Exception e) {}
        }
    }
}

2. Avoid using reader.ready() in blocking mode

The ready() method checks if data is immediately available, but in blocking mode, readLine() will naturally wait until data arrives. Using ready() causes your loop to skip iterations if no data is present right now, leading to missed messages and unnecessary CPU usage. Just use while ((line = reader.readLine()) != null) as shown above—it will block until the server sends data or the connection is closed.

3. Don't mix character streams and byte streams

You're using PrintWriter (character stream) and DataOutputStream (byte stream) on the same Socket output stream. These streams have separate buffers, which can cause data to be sent out of order or not flushed properly. If you need to send both text commands and binary data, stick to byte streams for everything (use OutputStreamWriter for text if needed, but manage it carefully).

三、Delphi端代码的潜在问题

Your Delphi server has a small but important bug in the connection handling:

1. Incorrect assignment of ListView item data

In ServerSocket1ClientConnect, you set Item.Data := Socket.Data;—but Socket.Data is nil by default. Later, in PngReceived, you check Item.Data = ClientSocket, which will never be true. Fix this by assigning the Socket itself to the item data:

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Caption := IntToStr(Socket.Handle);
  Item.SubItems.Add(Socket.RemoteAddress);
  Item.SubItems.Add(Socket.RemoteHost);
  stat1.Panels.Items[1].Text := 'Conectado';
  // Assign the Socket itself, not Socket.Data
  Item.Data := Socket;
end;

2. Verify ThreadBlocking mode setup

Double-check that your ServerSocket1 component has its SocketType set to stStream and ThreadedEvent set to True (since you're using a custom thread via OnGetThread). ThreadBlocking mode requires these settings to work correctly.

总结

The connection failure has nothing to do with blocking mode—Android's Socket is already blocking by default. Fix the stream handling in your Android client, add the necessary permissions, correct the Delphi ListView data assignment, and you should be able to establish a connection and exchange data properly.

内容的提问来源于stack exchange,提问作者user9120317

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:58:16