适用于Android仿真器的套接字有效,但不适用于实际设备

时间:2019-01-30 23:01:12

标签: android sockets android-emulator

我有Java代码,可通过ip将字符串发送到python脚本。该代码与模拟器完全兼容,但是当我通过usb将应用程序成功安装到手机上时,该代码无法正常工作。这是代码:

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {
    public String message;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button btn_python = findViewById(R.id.python);
        final Button btn_movie = findViewById(R.id.movie);
        final Button btn_hw = findViewById(R.id.homework);
        btn_python.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view1) {
                send py = new send();
                message = "python";
                Log.i("Button", "Button works");
                System.out.println("whatever");
                py.execute();
            }
        });
        btn_movie.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view2) {
                send mov = new send();
                message = "movie";
                mov.execute();
            }
        });
        btn_hw.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view2) {
                send hw = new send();
                message = "homework";
                hw.execute();
            }
        });
    }
    class send extends AsyncTask<Void,Void,Void>{
        Socket s;
        PrintWriter pw;
        @Override
        protected Void doInBackground(Void...params) {
            System.out.println("whatevernumbertwo");
            try {
                System.out.println("whatevernumberthree");
                s = new Socket("ip address", 7800);
                Log.i("Socket", "connects to socket");
                pw = new PrintWriter(s.getOutputStream());
                Log.i("output stream", "Output stream works");
                pw.write(message);
                Log.i("write", "Write works");
                pw.flush();
                Log.i("flush", "Flush works");
                pw.close();
                s.close();
            } catch (UnknownHostException e) {
                System.out.println("Fail");
                e.printStackTrace();
            } catch (IOException e) {
                System.out.println("Fail");
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }  
            return null;
        }
    }
}

正如我提到的,这在模拟器上有效,但在实际设备上无效。还提供了适当的权限。我究竟做错了什么?预先感谢。

1 个答案:

答案 0 :(得分:1)

经过大量挖掘,结果一直是服务器的防火墙。这就解释了为什么(显然)没有抛出异常,以及为什么代码似乎没有执行。 正在执行,只是卡在Socket()内(在连接期间)。

实际上,Socket()当然是在抛出IOException;可能只需要一段时间。

该代码可在仿真器上运行,因为在同一台计算机上运行时,它位于防火墙后面。