Android Studio(Java)客户端无法连接Android服务端问题求助
客户端无法连接TCP Socket服务端排查方案
近期刚学习TCPSocket,希望使用Android Studio开发在线答题APP,但客户端运行时无法连接到服务端,反复查阅资料、检查代码仍未解决。以下是相关代码和日志:
服务端代码
public class ServerWaitStart extends AppCompatActivity { private static GlobalVariable gv; private ServerSocket serverSocket; TextView currentNum; private int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_11_server_wait_start); gv = (GlobalVariable)getApplicationContext(); TextView IPaddress = findViewById(R.id.IPaddress); gv.IP = getLocalIP(this); IPaddress.setText("群組代碼:" + gv.IP); currentNum = findViewById(R.id.currentNum); serverConnect(); } private ServerThread serverThread; public void serverConnect(){ try { serverSocket= new ServerSocket(5050); } catch (IOException e) { throw new RuntimeException(e); } serverThread = new ServerThread(); serverThread.startServer(); } class ServerThread extends Thread implements Runnable{ private boolean serverRunning; private int count = 1; public void startServer(){ serverRunning = true; start(); System.out.println("startServer execute"); } @Override public void run() { try { while(serverRunning){ System.out.println("in run"); Socket socket = serverSocket.accept(); System.out.println("accept!"); count++; runOnUiThread(new Runnable() { @Override public void run() { try { DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeUTF(count + "\n"); // 立即發送 dos.flush(); currentNum.setText("目前已加入人數" + count); } catch (IOException e) { throw new RuntimeException(e); } } }); if (gv.chooseNum == count){ break; } } } catch (IOException e) { throw new RuntimeException(e); } } }//ServerThread
客户端代码
public class ClientWaitStart extends AppCompatActivity { private GlobalVariable gv; private TextView currentNum; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_07_client_wait_start); currentNum = findViewById(R.id.currentNum); gv = (GlobalVariable)getApplicationContext(); } private Runnable Connection=new Runnable() { @Override public void run() { try { Socket socket = new Socket("10.0.2.16", 5050); System.out.println("client connected"); DataInputStream dis = new DataInputStream(socket.getInputStream()); String waitPeopleNum = dis.readUTF(); runOnUiThread(new Runnable() { @Override public void run() { currentNum.setText("目前已加入人數;" + waitPeopleNum); } }); } catch (IOException e) { throw new RuntimeException(e); } } };
服务端日志
2023-06-02 13:22:19.504 5063-5063 System.out com.appcompat.app.quiz I startServer execute 2023-06-02 13:22:19.505 5063-5315 System.out com.appcompat.app.quiz I in run
排查要点
- 网络与IP一致性:
- 服务端通过
getLocalIP(this)获取IP并显示在界面,需确认该IP和客户端硬编码的10.0.2.16是否一致,可在服务端日志中打印gv.IP的值验证。 - 若为模拟器+真机组合测试:Android模拟器访问真机服务端需用真机的局域网IP;若均为真机,确保在同一WiFi网络下,且设备防火墙未拦截5050端口。
- 服务端通过
- 权限配置:
- Android 9+需在
AndroidManifest.xml中添加android:usesCleartextTraffic="true",允许明文Socket连接;同时必须添加网络权限:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- Android 9+需在
- 客户端线程启动:
- 客户端仅定义了
ConnectionRunnable,但未看到启动代码,需在合适时机(如按钮点击、onResume方法)调用new Thread(Connection).start();,且绝对不能在主线程直接执行Socket连接,否则会触发NetworkOnMainThreadException。
- 客户端仅定义了
- 服务端代码优化与验证:
ServerThread无需同时继承Thread和实现Runnable,直接继承Thread即可。- 服务端日志仅显示
in run,说明serverSocket.accept()一直处于阻塞等待状态,证明客户端连接请求未到达服务端,优先排查网络和IP问题。 - 避免在
runOnUiThread中执行Socket IO操作,应将IO逻辑放在子线程,UI线程仅负责更新界面。
- 端口占用检查:
- 可尝试更换端口(如8888)测试,排除5050端口被其他应用占用的可能。
内容的提问来源于stack exchange,提问作者llaimo
相关产品推荐
相关产品推荐

