簡體   English   中英

Android套接字已連接但無法寫入

[英]Android socket connects but cant write to it

我試圖在我的應用程序中進行一些聯網,但是遇到一些問題。 看來我無法寫入OutputStream對象。 盡管我的服務器接收到該連接,但它沒有接收到任何數據。 我試過使用Writer,DataOutputStream等。 似乎沒有一個工作。 我的應用程序使用異步任務,該任務通過Socket對象和消息來調用此對象。 (使用setStreams方法初始化后,套接字對象已經用於設置Streams。)有人可以嘗試查找問題嗎? 我將非常感謝。

public class NetworkingUtils {
private OutputStream out = null;
private InputStream in = null;

//set streams
public void setStreams(Socket sock){
    if (sock.isConnected()) {
        try {
            this.out = (OutputStream) sock.getOutputStream();
            this.in = (InputStream) sock.getInputStream();
        } catch (Throwable e) {
            Log.d("SOCKET", "FAILED TO SET STREAMS");
            e.printStackTrace();
        }
    }
}

//send \n terminated messages to pre defined socket
public void sendMessage(Socket sock, String message) throws Throwable {
    if (sock.isConnected()) {
        try {
            this.out.write(message.getBytes());
            Log.d("SOCKET","WRITING COMPLETE. " + message);
        } catch (Throwable e) {
            throw e;
        }
    }
}

public String recvMessage(Socket sock) throws Throwable {
    //receives \n terminated message from pre defined socket
    String answer = null;
    if (sock.isConnected()){
        try{
            answer = this.convertStreamToString(this.in);
            Log.d("SOCKET","READING COMPLETE");
        }
        catch (Throwable e){
            Log.d("socket",e.getLocalizedMessage());
            throw e;
        }
    }
    else{
        Log.d("socket","is not connected!!!");
    }
    if (answer.length() == 0){
        //empty string answer from server
        throw new IOException();
    }
    else {
        return answer;
    }

}

private String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = null;
    try{
     s = new java.util.Scanner(is).useDelimiter("\r\n");}
    catch (Throwable e){
        e.printStackTrace();
    }
    return s.hasNext() ? s.next() : "";
}

}

我只能看到一個可能導致此問題的客戶端...,對此我表示懷疑。 (這就是說:嘗試一下,以防萬一它有所作為,但我認為不會。)

  this.out.write(message.getBytes());
  Log.d("SOCKET","WRITING COMPLETE. " + message);

潛在的問題是,如果out是“緩沖”流,則write可能只會導致將字節寫入緩沖區。 可能需要調用this.out.flush()以“推送”到服務器。

但是我懷疑它是否會有所幫助,因為(據我所知)套接字輸出流沒有在Java中緩沖。 我認為真正的問題更有可能在服務器端。

如果您不知道該問題出在哪一邊,建議您嘗試使用網絡監視/數據包嗅探工具(在服務器端)檢查數據是否到達服務器主機。


在引起您注意的同時,您的異常代碼確實非常糟糕。

  1. 不要throws Throwable聲明為throws Throwable (或throws Exception )。 基本上就是說“此方法可能會拋出任何異常,而我沒有告訴您是哪個”。 當您執行此操作時,調用者代碼必須處理任何異常,這基本上不可能明智地執行。

    應該做的是將方法聲明為拋出代碼可以拋出的已檢查異常。 例如,在您的情況下, IOException可能就足夠了。

  2. 捕獲異常,記錄並重新拋出異常不是一個好主意。 為什么? 因為在堆棧的更遠處,可能還有其他方法將看到異常。 他們不知道該異常是否已經記錄。 因此,他們應該記錄它(可能導致相同問題的重復日志事件)還是不記錄(可能導致未記錄的異常)。

  3. 不要在沒有消息的情況下拋出異常:

      throw new IOException(); 

    很懶 您應該始終包含一條簡單的消息,該消息至少可以被grep或google搜索。

此外,您無需在整個位置測試Socket.isConnected() 根據javadoc:

返回:如果套接字已成功連接到服務器,則返回true

注意:關閉套接字不會清除其連接狀態,這意味着如果已關閉的套接字在關閉之前已成功連接,則此方法將對關閉的套接字返回true(請參見isClosed())。

因此,反復測試isConnected是無效的。 如果返回true一次,它會總是返回true從那時起。

甚至setStreams的初始isConnected測試都是可疑的。 我只是調用getInputStream而不進行測試,並且如果套接字處於錯誤狀態,則依靠Socket API拋出IOException

您實際上是在使用晦澀的Scanner使用來讀取行,但不是在編寫行。 因此,掃描儀將阻塞直到行終止器或EOS到達為止。

發送時需要附加行終止符。

暫無
暫無

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

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