Android TCP 在套接字关闭之前不会刷新 [英] Android TCP does not flush until socket is closed

查看:30
本文介绍了Android TCP 在套接字关闭之前不会刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试各种实现来实现这一目标,并在 StackOverflow 和 Android 开发人员中搜索了解决方案,但我在编程方面没有太多经验,无法使该块代码正常工作.

I have been trying various implementations to make this work, and have searched StackOverflow and Android Developers for a solution, but I am not too experienced in programming and cannot get this block to code to work properly.

我的意图:

  1. 这是在一个线程中,它将循环检查是否有 outMessage,如果有,它将发送消息.
  2. 接下来它会检查流中是否有任何内容,如果有,它会将其发送到我的主要活动中的处理程序.
  3. 最后,它会休眠 1 秒,然后再次检查.
  4. 这应该允许我多次读/写而无需关闭和打开套接字.

问题:

  • 在我关闭套接字之前,外流不会被刷新.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" , "
" + "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 服务器,直到我将其移植到真实服务器上:

The java server I found online and am using until I port this over to the real server:

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!
");

        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() + '
';
                System.out.println("Out to client (" + ip + "): "
                        + capitalizedSentence);
                outToClient.writeBytes(capitalizedSentence + "
");
            }

        }
    } 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!
");

    }
}

private static void getIp() {
    InetAddress ipAddr;
    try {
        ipAddr = InetAddress.getLocalHost();
        System.out.println("Current IP address : "
                + ipAddr.getHostAddress());

    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
}
}

推荐答案

我怀疑您是在消费者处读台词,但您并没有在写台词,因此消费者会一直阻塞,直到它获得 EOS 并交付一大行.根据需要在发送时添加行终止符.

I suspect you are reading lines at the consumer, but you aren't writing lines, so the consumer blocks until it gets EOS and delivers one big line. Add line terminators when sending as necessary.

这篇关于Android TCP 在套接字关闭之前不会刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆