【发布时间】:2012-08-04 12:49:37
【问题描述】:
我一直在尝试各种实现来完成这项工作,并在 StackOverflow 和 Android 开发人员中搜索了解决方案,但我在编程方面没有太多经验,无法让这个代码块正常工作。
我的意图:
- 这是一个线程,将循环检查是否有 outMessage,如果有,它将发送消息。
- 接下来,它会检查流内是否有任何内容,如果有,它会将其发送到我的主要活动中的处理程序。
- 最后,它会休眠 1 秒,然后再次检查。
- 这应该允许我多次读/写,而无需关闭和打开套接字。
问题:
- 在我关闭套接字之前,外流不会被刷新。 flush() 似乎没有效果。
我的要求:
- 请发布使此代码正常工作所需的更改,如上文所述(任何解释为什么的注释将不胜感激。指向其他类似问题/答案的链接将非常有助于我学习,但我一直在看那些几个星期,但无法让它工作,所以请确保您还包括此代码所需的更改,以便按上述方式工作。提前致谢。
其他:
- 我想知道我的插播和/或插播是否需要查找行尾字符?
- 这里会使用 TCP_NODELAY 之类的东西吗?
- 我们将不胜感激任何可以提供的额外信息。我想好好学习这方面的东西,但目前我什么都做不了。
代码:
public void run() {
while (connectionStatus == TCP_SOCKET_STATUS_CONNECTED) {
try {
if (outMessage != null){
OutStream.writeBytes(outMessage);
OutStream.flush();
outMessage = ("OUT TO SERVER: " + outMessage);
// socketClient.close();
sendMessageToAllUI(0, MAINACTIVITY_SET_TEXT_STATE, "appendText" , outMessage);
outMessage = null;
}
if (InStream != null) {
String modifiedSentence = InStream.readLine();
sendMessageToAllUI(0, MAINACTIVITY_SET_TEXT_STATE, "appendText" , "\n" + "IN FROM SERVER: " + modifiedSentence);
}
Thread.sleep(1000);
} catch (IOException e) {
connectionLost();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
制作套接字的线程:
public void run() {
if(I) Log.i(LOGTAG, "Attempt Connection with IP: " + serverIP + " ...");
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) {
if(I) Log.i(LOGTAG," ...UnknownException e: e.getMessage() shows: " + e.getMessage());
connectionFailed();
} catch (SocketTimeoutException e) {
if(I) Log.i(LOGTAG," ...SocketTimoutException e: e.getMessage() shows: " + e.getMessage());
connectionFailed();
} catch (IOException e) {
if(I) Log.i(LOGTAG," ...caught on run()");
// Close the socket
try {
tempSocketClient.close();
} catch (IOException e2) {
Log.e(LOGTAG, "unable to close() socket during connection failure", e2);
}
if(I) Log.i(LOGTAG," ...IOException e: e.getMessage() shows: " + e.getMessage());
connectionFailed();
return;
}
}
我在网上找到并使用的 java 服务器,直到我将它移植到真实服务器:
public class Server {
private static String SERVERIP;
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String clientSentence;
String capitalizedSentence;
try {
ServerSocket welcomeSocket = new ServerSocket(8888);
getIp();
System.out.println("Connected and waiting for client input!\n");
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
String ip = connectionSocket.getInetAddress().toString()
.substring(1);
System.out.println("In from client (" + ip + "): "
+ clientSentence);
if (clientSentence != null) {
capitalizedSentence = clientSentence.toUpperCase() + '\n';
System.out.println("Out to client (" + ip + "): "
+ capitalizedSentence);
outToClient.writeBytes(capitalizedSentence + "\n");
}
}
} catch (IOException e) {
// if server is already running, it will not open new port but
// instead re-print the open ports information
getIp();
System.out
.println("Server connected and waiting for client input!\n");
}
}
private static void getIp() {
InetAddress ipAddr;
try {
ipAddr = InetAddress.getLocalHost();
System.out.println("Current IP address : "
+ ipAddr.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
【问题讨论】:
-
消息有多大?它们是在不同的线程中生成的吗?没有锁定?
-
首先,消息大多是小字符串。诸如“转身”或“直走”之类的东西。也可能有多线的,但仍然很短。其次,如果您的意思是阻止,我不这么认为,但我对它的工作方式/如何检查感到有些困惑。我很确定它只会在创建套接字时阻塞。这应该在任何地方阻塞吗?如果您确实是指“锁定”,我不知道在这种情况下是什么意思。
-
我的意思是 锁定 避免线程之间的竞争条件。我的问题是
outMessage是在哪里创建的? -
mSocket.setTcpNoDelay(on);是我如何解释this,但是eclipse要我初始化“on”我设置do boolean on = true; ?我应该在创建套接字时执行这些操作,因为状态应该是持久的?
-
outMessage 是我服务中的静态成员。它目前是一个字符串,但一旦套接字正常工作,我最终会将其更改为队列。此方法位于服务内的嵌套类中。所以我可以在可以绑定到服务的多个活动之间保持套接字打开
标签: android sockets tcp flush dataoutputstream