这是this question的延续,因为它回答了我的原始问题,但没有解决该错误.
题:
>如何修复此行中的代码inStream.readline()
我的意图:
>这是一个线程,该线程将循环检查是否存在outMessage,如果存在,则将发送消息.
>接下来,它将检查插播广告中是否有内容,如果有,它将发送到我的主要活动中的处理程序.
>最后,它将休眠1秒钟,然后再次检查.
>这应该使我无需关闭和打开插座即可多次读取/写入.
问题:
>读写更好,但仍无法正常工作
现在正在发生什么:
>如果使用值初始化outMessage,则在与服务器连接时,套接字:
>写入并刷新值(服务器接收并响应)
>更新outMessage的值(根据我的硬编码方式,将其更新为null或“ x”)
>读取并显示来自服务器的响应消息
>重新进入下一个循环
>如果我将outMessage设置为null,它将跳过if语句正确然后挂起的情况;否则,如果我将outMessage设置为字符串(让我们说“ x”),它将遍历整个if语句,然后挂起.
>挂起的代码是inStream.readline()调用中的任何一个(我目前有一个注释掉了).
附加信息:
-连接后,我可以在“发送”框中键入内容,提交(更新outMessage值),然后断开连接.重新连接后,它将读取值并再次执行序列,直到它卡在同一行上.
自引用问题以来的变化:
-将outMessage和connectionStatus都设置为“ volatile”
-在必要的地方添加了行尾定界符.
码:
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,但后来又撤回了
解决方法:
您需要检查是否有可用数据:
if (InStream.available > 0) {
String modifiedSentence = InStream.readLine();
sendMessageToAllUI(0, MAINACTIVITY_SET_TEXT_STATE, "appendText" , "IN FROM SERVER: " + modifiedSentence);
}
但老实说,即使那样也不是很理想,因为您无法保证会收到首发信息.如果服务器发送了几个字节,但从不发送行尾,那么您将永远被阻塞.生产套接字代码不应依赖于readLine,而应读入缓冲区并检查该缓冲区的行尾(或协议需要的任何条件).
阅读不够仔细,我认为InStream是一个InputStream实例. InputStream可用. InputStreamReader已准备就绪(依次调用InputStream.available.只要您保留对这两个方法的引用,就可以查看是否有数据可供读取.