【发布时间】:2012-08-06 02:02:54
【问题描述】:
这是this question 的延续,因为它回答了我的原始问题,但没有解决错误。
问题:
- 如何修复挂在这一行的代码inStream.readline()
我的意图:
- 这是一个线程,将循环检查是否有 outMessage,如果有,它将发送消息。
- 接下来,它会检查流内是否有任何内容,如果有,它会将其发送到我的主要活动中的处理程序。
- 最后,它会休眠 1 秒,然后再次检查。
- 这应该允许我多次读/写,而无需关闭和打开套接字。
问题:
- 读写更好,但还是不能正常工作
现在发生了什么:
- 如果 outMessage 用一个值初始化,在与服务器连接时,套接字:
- 写入并刷新值(服务器接收并响应)
- 更新 outMessage 的值(为 null 或“x”,具体取决于我对其进行硬编码的方式)
- 读取并显示来自服务器的响应消息
- 重新进入下一个循环
- 如果我将 outMessage 设置为 null,它会跳过 if 语句正确然后挂起;否则,如果我将 outMessage 设置为一个字符串(比如说“x”),它会遍历整个 if 语句,然后挂起。
- 它挂起的代码是 inStream.readline() 调用之一(我目前已注释掉一个)。
附加信息: - 连接后,我可以在“发送”框中输入,提交(更新 outMessage 值),然后断开连接。重新连接后,它将读取值并再次执行序列,直到卡在同一行。
自引用问题以来的变化: - 使 outMessage 和 connectionStatus 都“易变” - 在必要的地方添加了行尾分隔符。
代码:
public void run() {
while (connectionStatus != TCP_SOCKET_STATUS_CONNECTED) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (connectionStatus == TCP_SOCKET_STATUS_CONNECTED) {
try {
if (outMessage != null){
OutStream.writeBytes(outMessage + "\n");
OutStream.flush();
sendMessageToAllUI(0, MAINACTIVITY_SET_TEXT_STATE, "appendText" , "OUT TO SERVER: " + outMessage);
outMessage = "x";
}
Thread.sleep(100);
// if (InStream.readLine().length() > 0) {
String modifiedSentence = InStream.readLine();
sendMessageToAllUI(0, MAINACTIVITY_SET_TEXT_STATE, "appendText" , "IN FROM SERVER: " + modifiedSentence);
// }
Thread.sleep(1000);
} catch (IOException e) {
connectionLost();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
制作套接字的线程:
public void run() {
setName("AttemptConnectionThread");
connectionStatus = TCP_SOCKET_STATUS_CONNECTING;
try {
SocketAddress sockaddr = new InetSocketAddress(serverIP, port);
tempSocketClient = new Socket(); // Create an unbound socket
// This method will block no more than timeoutMs. If the timeout occurs, SocketTimeoutException is thrown.
tempSocketClient.connect(sockaddr, timeoutMs);
OutStream = new DataOutputStream(tempSocketClient.getOutputStream());
InStream = new BufferedReader(new InputStreamReader(tempSocketClient.getInputStream()));
socketClient = tempSocketClient;
socketClient.setTcpNoDelay(true);
connected();
} catch (UnknownHostException e) {
connectionFailed();
} catch (SocketTimeoutException e) {
connectionFailed();
} catch (IOException e) {
// Close the socket
try {
tempSocketClient.close();
} catch (IOException e2) {
}
connectionFailed();
return;
}
}
服务器:
public static void main(String[] args) throws IOException {
String clientSentence;
String capitalizedSentence;
try {
ServerSocket welcomeSocket = new ServerSocket(8888);
SERVERIP = getLocalIpAddress();
System.out.println("Connected and waiting for client input!\n Listening on IP: " + SERVERIP +"\n\n");
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
while(true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clientSentence = inFromClient.readLine();
System.out.println("clientSentance == " + clientSentence);
String ip = connectionSocket.getInetAddress().toString().substring(1);
if(clientSentence != null)
{
System.out.println("In from client ("+ip+")("+ System.currentTimeMillis() +"): "+clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence + '\n');
System.out.println("Out to client ("+ip+"): "+capitalizedSentence);
}
}
} catch (IOException e) {
//if server is already running, it will not open new port but instead re-print the open ports information
SERVERIP = getLocalIpAddress();
System.out.println("Connected and waiting for client input!\n");
System.out.println("Listening on IP: " + SERVERIP +"\n\n");
}
}
提前致谢!
编辑:
- 更新后添加服务器代码
- 我尝试为套接字设置 SoTimout,但又取消了
【问题讨论】:
-
为什么这是个问题?听起来这正是您对代码所期望的行为。在这种情况下,您希望它做什么? (另外,摆脱这个
socketClient.setTcpNoDelay(true);。它不能解决任何问题。) -
它正在发送>接收>下一个循环正确,但它确实发送>?并且我的服务器上没有任何显示+它无限期地等待服务器响应=第一次通过后套接字当前无用。 outStream 没有发送它对我来说没有意义(因为它第一次做得很好)。也许我问错了问题?我正在研究如何从服务器端监视 TCP 连接以查看所有数据包......但我还没有设法做到这一点
-
您的代码旨在无限期地等待服务器的响应。套接字是无用的,因为您的代码选择永远等待响应,即使服务器不需要发送响应也是如此。
-
正确,所以我正在寻找的是如何使情况并非如此。我想让它检查是否有东西要发送,如果有,就发送。然后,检查是否有要读入的内容,如果有,请阅读并将其发送到我的另一个线程的处理程序。我希望它不断检查一个,然后另一个,然后再做一次。我可以为读取尝试添加一个超时计数器,但我在想其他人可能会建议一个不同的 if 语句或其他东西以便它检查,然后立即继续阅读那里的内容,或者只是继续前进并在下一次再次检查循环。
-
只有在有可用数据的情况下才执行您的
readLine和sendMessageToAllUI。用if (InStream.available > 0) { /* readLine and sendToUI */ }包裹这两个语句
标签: android sockets tcp inputstream