[英]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中緩沖。 我認為真正的問題更有可能在服務器端。
如果您不知道該問題出在哪一邊,建議您嘗試使用網絡監視/數據包嗅探工具(在服務器端)檢查數據是否到達服務器主機。
在引起您注意的同時,您的異常代碼確實非常糟糕。
不要throws Throwable
聲明為throws Throwable
(或throws Exception
)。 基本上就是說“此方法可能會拋出任何異常,而我沒有告訴您是哪個”。 當您執行此操作時,調用者代碼必須處理任何異常,這基本上不可能明智地執行。
您應該做的是將方法聲明為拋出代碼可以拋出的已檢查異常。 例如,在您的情況下, IOException
可能就足夠了。
捕獲異常,記錄並重新拋出異常不是一個好主意。 為什么? 因為在堆棧的更遠處,可能還有其他方法將看到異常。 他們不知道該異常是否已經記錄。 因此,他們應該記錄它(可能導致相同問題的重復日志事件)還是不記錄(可能導致未記錄的異常)。
不要在沒有消息的情況下拋出異常:
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.