簡體   English   中英

TCP 客戶端套接字掛在服務器套接字上

[英]TCP Client socket hanging the Server Socket

我正在開發一個 TCP/IP 套接字程序來將我的 Android 手機與我的服務器 PC 連接起來。

我創建了一個簡單的 echo 程序。

連接到服務器后,我可以發送我的注冊命令而不會出現任何問題/延遲/掛起。

在我使用我的緩沖閱讀器接收后,我將數據傳遞給我的主要活動中的函數,實習生通過寫入 OutputStream 將這些數據發送到服務器。 當我的客戶端發送此數據時,我的服務器掛起(忙等待 - > 我猜)但 5 秒后它恢復正常操作並成功接收數據。 甚至我的工作線程(AsyncTask)也掛了,這很明顯,因為與其他消息相比,它們在 Logcat 中顯示消息有明顯的延遲。

安卓工作室 3.3.1

目標 API 級別:>= 26 (8.0 Oreo)

TCP 測試服務器 - Hercules

@SuppressLint("StaticFieldLeak")
public void connect(){
    new AsyncTask<Void, Void, Boolean>(){

        @Override
        protected Boolean doInBackground(Void... voids) {
            try {
                socket  = new Socket(ip, portNo);
                out     = socket.getOutputStream();
                in      = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                socketAlive.set(true);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(result){
                sendData("RegisterDevice:<ip>:<mac>");
                readerThread();
            }
            else{
                socketAlive.set(false);
                reconnect();
            }
        }
    }.execute();
}
@SuppressLint("StaticFieldLeak")
public void sendData(final String data){
    if(this.socket == null || this.socket.isClosed() )
    {
        //Unable to send data as output is closed returning
        return;
    }
    new AsyncTask<String, Void, Boolean>(){
        @Override
        protected Boolean doInBackground(String... writeString) {
            try {

out.write(writeString[0].getBytes()); // -->> 導致服務器套接字掛起

                //out.flush();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(!result) {
                reconnect();
                sendData(data);
            }
        }
    }.execute(data);
}

@SuppressLint("StaticFieldLeak")
public void readerThread(){
    if(this.socket.isClosed())
    {
        //Unable to recieve data as output is closed returning
        return;
    }
    new AsyncTask<Void, Void, Boolean>(){
        @Override
        protected Boolean doInBackground(Void... voids) {
            try {
                Arrays.fill(readBuffer, '\0');
                //in.read(readBuffer, 0, Ethernet.TCP_READ_BUFFER_SIZE);//8192
                in.read(readBuffer);
                return  true;

            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean result) {
            if(result) {
                //dataRead = String.copyValueOf(readBuffer, 0, Ethernet.TCP_READ_BUFFER_SIZE);
                String str = String.copyValueOf(readBuffer);
                str.trim();
                Log.i("Test", "Test");
                mainActivity.processEthernetData(String.copyValueOf(readBuffer, 0, Ethernet.TCP_READ_BUFFER_SIZE));
                Log.i("ReadInfo", String.copyValueOf(readBuffer, 0, Ethernet.TCP_READ_BUFFER_SIZE));
                readerThread();
            }
            else {
                reconnect();
            }
        }
    }.execute();
}

public void processEthernetData(final String protcol){

    eth.sendData(protcol);
}

問題是由

mainActivity.processEthernetData(String.copyValueOf(readBuffer, 0, Ethernet.TCP_READ_BUFFER_SIZE));

顯然,創建並傳遞給函數的字符串是按TCP_READ_BUFFER_SIZE順序排列的,其中值TCP_READ_BUFFER_SIZE當通過 TCP/IP 傳輸如此大的字符串時,它會導致我的服務器暫時掛起,直到它收到完整的數據。

我通過將行更改為

mainActivity.processEthernetData(String.copyValueOf(readBuffer, 0, ethernetBytesRead)); 

暫無
暫無

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

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