簡體   English   中英

與(外部)Python服務器的網絡連接

[英]Network connection to (external) Python server

我創建了一個Java客戶端,該客戶端應連接到python服務器。 作為一個獨立的設備,它可以很好地工作,可以建立連接並且可以發送數據。

public class ClientTest {

    public static void main(String args[]) {
        requestGazeData();
    }

    public static void requestGazeData() {
        ZMQ.Context context = ZMQ.context(1);
        ZMQ.Socket request = context.socket(ZMQ.REQ);
        request.connect("tcp://xxx.x.x.x:50020");

        // Ask for the sub port
        request.send("SUB_PORT");
        String subPort = request.recvStr();
        System.out.println("subPort: " + subPort);

        // open a sub port to listen to pupil
        ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
        subscriber.connect("tcp://xxx.x.x.x:" + subPort);

        String gaze = "gaze";
        subscriber.subscribe(gaze.getBytes(Charset.forName("UTF-8")));

        while (true) {
            String msg = subscriber.recvStr();
            System.out.println(msg);

            subscriber.close();
            context.term();
        }
    }
}

現在,該客戶端必須在應用程序啟動后運行,但是什么也沒有發生。 我沒有從服務器獲取任何數據,並且卡住了。 從Android方面來看,這絕對是一個問題,我認為尤其是活動類。 這個看起來如下:

public class MainActivity extends Activity {

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

        // Set function for button
        findViewById(R.id.button).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        ClientTest.requestGazeData();
                    }
                });

    }
}

我也不例外。 在我的Manifest.xml ,放入所有需要的權限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

最后,我允許在防火牆端口上進行連接(通過Ubuntu中的ufw)。 我已經沒有足夠的想法來解決它並使它工作。

更新:由於一個可能的答案,我嘗試了AsyncTask ,但仍然發生任何事情。 這是我更新的活動課程:

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

        // Set function for the button
        findViewById(R.id.connectButton).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        new NetworkCall().execute("");
                    }
                });
    }

    private class NetworkCall extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            ZMQ.Context context = ZMQ.context(1);
            ZMQ.Socket request = context.socket(ZMQ.REQ);
            request.connect("tcp://xxx.x.x.x:50020");

            System.out.println("Connected");
            // ask for the sub port
            request.send("SUB_PORT");
            String subPort = request.recvStr();
            System.out.println("subPort: " + subPort);

            //int subPortNo = Integer.parseInt(subPort);

            // open a sub port to listen to pupil
            ZMQ.Socket subscriber = context.socket(ZMQ.SUB);
            subscriber.connect("tcp://xxx.x.x.x:" + subPort);

            String gaze = "gaze";
            subscriber.subscribe(gaze.getBytes(Charset.forName("UTF-8")));

            while (true) {
                String msg = subscriber.recvStr();
                System.out.println(msg);

                //subscriber.close();
                //context.term();
            }
        }

        @Override
        protected void onPostExecute(String result) {
            System.out.println("DONE");
        }

        @Override
        protected void onPreExecute() {}

        @Override
        protected void onProgressUpdate(Void... values) {}
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

您無法在Android的主線程中調用進行網絡通信的函數。 您需要將此任務傳遞給AsyncTask ,它將正常工作。

這是一個AsyncTask的示例,可能會對您有所幫助。

private class NetworkCall extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        Data data = ClientTest.requestGazeData();
        return data.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        // Do something with your data.toString();
    }

    @Override
    protected void onPreExecute() {}

    @Override
    protected void onProgressUpdate(Void... values) {}
}

現在,只需單擊您的button即可啟動AsyncTask

findViewById(R.id.button).setOnClickListener(
    new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new NetworkCall().execute("");
        }
    });

因此,在嘗試了所有內容之后,我禁用了防火牆,最后連接正常。 有時可能是很小的細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM