[英]Android reading from Socket hangs on second read loop
我必須在我的應用程序中實現聊天。 使用套接字連接到服務器。 我應該注冊到該服務器,服務器將通過回復知道。
我已經在一個方法中實現了這個,我使用BufferedWriter發送命令,然后從輸入流開始讀取,直到它告訴我沒有更多的數據。
我正確閱讀了服務器回復。 但是,我從來沒有從第二個in.read
調用中得到負值,因此我的方法在while循環中被阻塞(在我調用的條件語句中)。
如何用套接字完成? 我通常使用文件或其他輸入流沒有問題。
如果我只讀取我應該閱讀的字節,這是否意味着我要么:
目前我正在做以下事情:
private String sendSocketRequest(String request, boolean skipResponse) throws ChatException {
if (!isConnected()) openConnection();
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream()), 2048);
out.append(request);
out.flush();
out = null;
} catch (IOException e) {
LogHelper.error("Unable to send socket request: " + request, e);
throw new ChatException("Unable to send socket request: " + request, e);
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()), 2048);
StringBuffer response = new StringBuffer();
char[] buffer = new char[2048];
int charsRead = -1;
// >>>>>>>> This is where it gets blocked <<<<<<<<<
while ((charsRead = in.read(buffer)) >= 0) {
if (charsRead > 0) response.append(new String(buffer, 0, charsRead));
}
return response.toString();
} catch (IOException e) {
LogHelper.error("Unable to read socket response: " + request, e);
throw new ChatException("Unable to read socket response: " + request, e);
}
}
使用以下方法連接到服務器:
public synchronized void openConnection() throws ChatException {
try {
socket = new Socket(Constants.API_CHAT_SERVER_ADDRESS, Constants.API_CHAT_SERVER_PORT);
socket.setKeepAlive(true);
LogHelper.debug("CHAT >> Connected to the chat server: " + Constants.API_CHAT_SERVER_ADDRESS);
} catch (UnknownHostException e) {
LogHelper.error("Unable to open chat connection", e);
throw new ChatException("Unable to open chat connection", e);
} catch (IOException e) {
LogHelper.error("Unable to open chat connection", e);
throw new ChatException("Unable to open chat connection", e);
}
}
通過基於套接字的連接發送/接收的數據量是協議依賴的,並且TCP / IP堆棧不知道,但僅限於應用層。
使用的協議是開發人員dependend ... ;-)所以提出你的問題:
如果我只讀取我應該閱讀的字節,這是否意味着我要么:
- 事先知道服務器響應的長度?
是的,這是一種可能性。
- 或者讓服務器發送代碼通知它已完成發送響應?
也是,因為這是另一種可能性。 常用標記是\\n
或\\r\\n
。 NUL
/ '\\0'
字符也可能有意義。
第三種選擇是為每個數據塊添加一個恆定數量的字節,用於描述要來的字節數。
也許它更簡單地處理ad-hoc類的實例,比如 - 例如 - Message類:而不是處理字節。
服務器:
// Streams
protected ObjectInputStream fromBuffer = null;
protected ObjectOutputStream toBuffer = null;
// Listening for a new connection
ServerSocket serverConn = new ServerSocket(TCP_PORT);
socket = serverConn.accept();
toBuffer = new ObjectOutputStream(socket.getOutputStream());
fromBuffer = new ObjectInputStream(socket.getInputStream());
// Receiving a new Message object
Message data = (Message)fromBuffer.readObject();
客戶端然后簡單地發送消息:
// Sending a message
Message data = new Message("Hello");
toBuffer.writeObject(data);
只要其成員實現Serializable接口, 消息就可以根據需要復雜化 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.