【问题标题】:Returning connected socket returns null返回连接的套接字返回 null
【发布时间】:2019-05-15 09:46:45
【问题描述】:

我正在尝试在 android 上创建一个客户端 - 服务器应用程序。我想要一个初始化套接字并将其返回给主类的类。我在创建和连接套接字时没有任何问题(我的服务器正在正确处理连接)但是当我尝试将创建的套接字返回到主类时它为空。我错过了什么?

我尝试过使用 AsyncTask。

这是主类的代码:

public class MainActivity extends AppCompatActivity {
    private Socket socket;
    private SocketHandler sH;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sH = new SocketHandler();
        sH.start();
        socket = sH.getSocket();

        if(socket == null){
             System.out.println("null");
        }else{
            System.out.println("not null");
        }
    }
}

这是初始化套接字的类的代码:

public class SocketHandler extends Thread {
    private Socket socket;

    public Socket getSocket(){
        return socket;
    }

    @Override
    public void run(){
        try{
            socket = new Socket("192.168.0.4", 9999);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 看起来像一个竞争条件
  • 您在SocketHandler 上调用start,这将启动一个新线程,该线程将在某个时候初始化socket 变量。然后在MainActivity 中调用getSocket,但此时不能保证socket 变量已经被初始化(这发生在一个单独的线程中)。

标签: java android sockets


【解决方案1】:

线程是并行运行的,这意味着不能保证您的套接字连接会立即完成,但是您错误地假设并且您踩到了经典的竞争条件,因为在您调用 getSocket() 的那一刻,连接仍在建立中(但此过程尚未完成),因此 socket 变量仍然是 null,因为它是在创建 SocketHandler 的实例时初始化的。

您需要同步代码、执行回调或(出于测试目的)在调用 getSocket() 之前稍等片刻或读取几次(即在循环中 + 一些延迟/超时,除非套接字值不是 @ 987654326@(但请注意,如果套接字连接失败,您需要期望 null 也是有效值)。

另外,如果你在单独的线程中创建,为什么要在主线程中读取套接字?你不应该在那个线程中做所有的套接字工作吗?

【讨论】:

  • 真的,谢谢!我将创建两个类(将在线程上扩展),它们将等待服务器消息并向服务器发送响应,因此我不能在同一个线程中同时执行这两个操作。
猜你喜欢
  • 2013-04-20
  • 2015-06-06
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
相关资源
最近更新 更多