Android的TCP不冲水,直到套接字关闭 [英] Android TCP does not flush until socket is closed

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

问题描述

我一直在尝试不同的实现方式,使这项工作,并且已经搜查计算器和Android开发的解决方案,但我没有太多经验的编程和不能得到这个块code才能正常工作。

我的意图:

  1. 这是在一个线程,将通过检查,如果有一个outMessage循环,如果有,则发送消息。
  2. 在接下来它会检查是否有在河道内,如果有,它会在我的主要活动发送到处理任何事情。
  3. 最后,它会睡1秒钟,然后再次检查。
  4. 这应该让我读/写多次,而无需关闭和打开插座。

问题:

  • 的outstream没有得到刷新,直到我关闭套接字。冲洗()似乎没有任何效果。

我的要求:

  • 请后得到这个code上述(任何注解来解释为什么会大大AP preciated正常工作所需的更改。链接到其他类似的问题/答案将是巨大的帮助我学习,但我一直在寻找那些几个星期,都无法得到它的工作,所以请确保您还包括改变这个code需求,以便如上所述。在此先感谢工作。

其他:

  • 我想知道如果我的河道内及放大器;?/或outstream需要寻找行结束字符
  • 会像TCP_NODELAY在这里使用?
  • 可以给予一定会很美联社preciated任何额外的信息。我想学这个东西很好,但我目前还不能得到任何工作。

code:

 公共无效的run(){
        而(connectionStatus == TCP_SOCKET_STATUS_CONNECTED){
            尝试 {
                如果(outMessage!= NULL){
                   OutStream.writeBytes(outMessage);
                   OutStream.flush();
                   outMessage =(OUT到服务器:+ outMessage);
                // socketClient.close();
                   sendMessageToAllUI(0,MAINACTIVITY_SET_TEXT_STATE,appendText,outMessage);
                   outMessage = NULL;
                }
                如果(视频插播广告!= NULL){
                    串modifiedSentence = InStream.readLine();
                    sendMessageToAllUI(0,MAINACTIVITY_SET_TEXT_STATE,appendText,\ N+从服务器:+ modifiedSentence);
            }
            视频下载(1000);
        }赶上(IOException异常E){
            失去连接();
            打破;
        }赶上(InterruptedException异常E){
                e.printStackTrace();
            }
    }
}
 

这使得插座上的螺纹:

 公共无效的run(){
        如果(我)Log.i(LOGTAG,尝试连接与IP:+服务器IP +...);
        的setName(AttemptConnectionThread);
        connectionStatus = TCP_SOCKET_STATUS_CONNECTING;
        尝试 {
            SocketAddress的套接字地址=新的InetSocketAddress(服务器IP,端口);
            tempSocketClient =新的Socket(); //创建一个未绑定的套接字

            //此方法将阻塞,不超过timeoutMs更多。如果出现超时,SocketTimeoutException如果被抛出。
            tempSocketClient.connect(套接字地址timeoutMs);
            OutStream =新DataOutputStream类(tempSocketClient.getOutputStream());
            视频插播广告=新的BufferedReader(新的InputStreamReader(tempSocketClient.getInputStream()));
            socketClient = tempSocketClient;
            socketClient.setTcpNoDelay(真正的);
            连接();
        }赶上(UnknownHostException异常E){
            如果(我)Log.i(LOGTAG,... UnknownException E:e.getMessage()表示:+ e.getMessage());
            连接失败();
        }赶上(SocketTimeoutException如果E){
            如果(我)Log.i(LOGTAG,... SocketTimoutException E:e.getMessage()表示:+ e.getMessage());
            连接失败();
        }赶上(IOException异常E){
            如果(我)Log.i(LOGTAG,......风行的run());
            //关闭套接字
            尝试 {
                tempSocketClient.close();
            }赶上(IOException异常E2){
                Log.e(LOGTAG,E2无法连接故障时关闭()套接字);
            }
            如果(我)Log.i(LOGTAG,... IOException异常E:e.getMessage()表示:+ e.getMessage());
            连接失败();
            返回;
        }
    }
 

Java服务器我在网上找到,并正在使用,直到我口这种过度到真正的服务器:

 公共类服务器{

私有静态字符串SERVERIP;

/ **
 * @参数ARGS
 * @throws IOException异常
 * /

公共静态无效的主要(字串[] args)抛出IOException异常{
    字符串clientSentence;
    字符串capitalizedSentence;

    尝试 {
        ServerSocket的welcomeSocket =新的ServerSocket(8888);
        getIp();
        的System.out.println(!连接并等待客户端输入的\ n);

        而(真){
            插座connectionSocket = welcomeSocket.accept();
            的BufferedReader inFromClient =新的BufferedReader(
                    新的InputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream类outToClient =新DataOutputStream类(
                    connectionSocket.getOutputStream());

            clientSentence = inFromClient.readLine();
            字符串IP = connectionSocket.getInetAddress()的toString()
                    .substring(1);
            的System.out.println(从客户端(+ IP +):
                    + clientSentence);
            如果(clientSentence!= NULL){
                capitalizedSentence = clientSentence.toUpperCase()+'\ N';
                的System.out.println(出到客户端(+ IP +):
                        + capitalizedSentence);
                outToClient.writeBytes(capitalizedSentence +\ N);
            }

        }
    }赶上(IOException异常E){
        //如果服务器已经在运行,它不会打开新的端口,但
        //而不是重新打印打开的端口信息
        getIp();
        System.out的
                .println(服务器连接并等待客户端输入\ N!);

    }
}

私有静态无效getIp(){
    InetAddress类IPADDR;
    尝试 {
        IPADDR = InetAddress.getLocalHost();
        的System.out.println(当前的IP地址
                + ipAddr.getHostAddress());

    }赶上(UnknownHostException异常E){
        e.printStackTrace();
    }
}
}
 

解决方案

我怀疑你正在阅读的消费者的线条,但你是不是写的线条,让消费者阻塞,直到它变得EOS,并提供一个大线。根据需要发送时添加行终止。

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.

My Intent:

  1. This is in a thread that will loop through checking if there is an outMessage, if there is, it will send the message.
  2. Next it will check it if there is anything in the in-stream, if there is, it will send it to the handler in my main activity.
  3. Lastly, it will sleep for 1 second, then check again.
  4. This should allow me to read/write multiple times without needing to close and open the socket.

Problem:

  • The outstream does not get flushed until I close the socket. flush() seems to have no effect.

My request:

  • Please post the changes required to get this code working properly as described above (any annotations to explain WHY would be greatly appreciated. Links to other similar questions/answers would be great to help me learn, but i have been looking at those for a couple weeks and just cant get it to work, so please make sure you also include the changed this code needs in order to work as described above. Thanks in advance.

Other:

  • I am wondering if my instream &/or outstream need to look for end-of-line characters?
  • Would something like TCP_NODELAY be used here?
  • Any extra info that can be given will be very appreciated. I want to learn this stuff well, but I currently cannot get anything to work.

Code:

 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();
            }
    }                           
}

The thread that makes the socket:

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;
        }
    } 

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

解决方案

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天全站免登陆