Android TCP在套接字关闭之前不会刷新
我一直在尝试各种实现来实现这一点,并在StackOverflow和Android开发人员中寻找解决方案,但我在编程方面没有太多经验,无法让这段代码正常工作 我的意图:Android TCP在套接字关闭之前不会刷新,android,sockets,tcp,flush,dataoutputstream,Android,Sockets,Tcp,Flush,Dataoutputstream,我一直在尝试各种实现来实现这一点,并在StackOverflow和Android开发人员中寻找解决方案,但我在编程方面没有太多经验,无法让这段代码正常工作 我的意图: 这是在一个线程中,该线程将循环检查是否有outMessage,如果有,它将发送消息 接下来,它将检查in-stream中是否有任何内容,如果有,它将把它发送给我的主活动中的处理程序 最后,它将休眠1秒,然后再次检查 这应该允许我读/写多次,而无需关闭和打开套接字 问题: 直到我关上插座,外流才被冲洗。flush()似乎没有效果
- 直到我关上插座,外流才被冲洗。flush()似乎没有效果
- 请发布所需的更改,以使此代码如上所述正常工作(任何解释原因的注释都将不胜感激。指向其他类似问题/答案的链接将非常有助于我的学习,但我已经看了几周了,只是无法使其正常工作,因此请确保您还包括此代码所需的更改,以便按上述方式工作。提前感谢
- 我想知道我的流内和/或流外是否需要查找行尾字符
- 这里会使用像TCP_NODELAY这样的东西吗
- 任何可以提供的额外信息都将非常感谢。我想好好学习这些东西,但我目前无法得到任何有用的东西
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();
}
}
}
由于这些是短消息(
),我猜堆栈可能正在实现Nagle的算法。服务器是否正在执行某种延迟确认?如果可能,您应该捕获跟踪,并查看是否有来自另一端的待定确认
在这两种情况下,
TCP\u NODELAY
都会有所帮助。我怀疑您正在消费者处读行,但您没有写行,因此消费者会阻止,直到它得到EOS并发送一条大行。在发送时根据需要添加行终止符。消息有多大?它们是在不同的线程中生成的吗?没有锁定?首先,在e消息大多是小字符串,比如“掉头”或“笔直行走”也可能有多行的,但仍然很短。第二,如果你是指阻塞,我不这么认为,但我对它的工作原理/如何检查有点困惑。我很确定它只在创建套接字时阻塞。这个阻塞应该在任何地方吗?如果你确实是指“锁定”我不知道在这个上下文中是什么。我的意思是锁定,以避免线程之间的竞争条件。我的问题是outMessage
是在哪里创建的?mSocket.setTcpNoDelay(on);是我如何解释的,但eclipse希望我初始化“on”我是否设置do boolean on=true;?由于状态应该是持久的,所以我在创建套接字时是否应该执行这些操作?outMessage是我的服务中的静态成员。它当前是一个字符串,但在套接字正常工作后,我最终会将其更改为队列。此方法位于服务中的嵌套类中。因此,我可以保持套接字运行在可以绑定到服务的多个活动之间1.ACK代表什么?我在谷歌上搜索了它,但找不到定义2.我会给你和Nikolai建议的TCP_NODELAY一个镜头,如果它确实回答了问题,mark会回答。感谢到目前为止的帮助!ACK是TCP确认。而不是为每个s发送ACK此外,服务器可能正在等待将其捆绑。如果客户端实现Nagle的algo,它将在发送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();
}
}
}