Android TCP 应用程序挂在 inStream.readline() 上

2023-11-29

这是一个延续这个问题因为它回答了我原来的问题,但它没有解决错误。

问题:

  • 如何修复挂在这一行的代码inStream.readline()

我的意图:

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

Problem:

  • 阅读和写作更好了,但仍然无法正常工作

现在发生了什么:

  • If outMessage is initialized with a value, upon connection with the server, the socket:
    1. 写入并刷新值(服务器接收并响应)
    2. 更新 outMessage 的值(为 null 或“x”,具体取决于我如何对其进行硬编码)
    3. 读取并显示来自服务器的响应消息
    4. 重新进入下一个循环
    5. IF i set outMessage to null, it skips over that if statements correctly then hangs; otherwise, if i set outMessage to a string (lets say "x"), it goes through the whole if statement, then hangs.
      • 代码它hangs on是其中之一inStream.readline()调用(我目前已经注释掉了一个)。

附加信息: - 连接后,我可以在“发送”框中键入内容,提交(更新 outMessage 值),然后断开连接。重新连接后,它将读取该值并再次执行该序列,直到卡在同一行上。

自引用问题以来的变化: - 使 outMessage 和 connectionStatus 均为“易失性” - 在必要的地方添加了行尾分隔符。

Code:

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

Server:

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

    }
}

提前致谢!

Edits:

  • 更新后添加了服务器代码
  • 我尝试为套接字设置 SoTimout,但又把它取消了

您的服务器经过专门设计,可以从客户端接收一行,并返回一行。看代码:

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

请注意,在循环内部,它接受一个新连接,读取一行,然后写入一行。它不会关闭连接。它并没有完全结束谈话。它只是停止阅读。

使用该服务器的客户端必须进行连接、发送一行、读回一行,然后客户端必须关闭连接。你的客户不会这样做。为什么?因为你不知道那是你必须做的。为什么?因为你没有设计……没有计划。

这就是你的具体问题。但是请让我敦促你采取huge退后一步,彻底改变你的方法。在编写一行代码之前,请实际设计并指定字节级别的协议。协议应该说明发送什么数据、如何分隔消息、谁何时发送、谁关闭连接等等。

否则,无法调试您的代码。看看上面的服务器代码,是否正确?好吧,谁知道呢。因为不清楚它应该做什么。当您编写客户端时,您假设服务器以一种方式运行。这个假设有效吗?服务器坏了吗?谁知道呢,因为没有规范服务器应该做什么。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android TCP 应用程序挂在 inStream.readline() 上 的相关文章

  • StrictMode 策略违规:我的应用程序中存在 android.os.strictmode.LeakedClosableViolation?

    Android 开发新手 第一次在我的应用程序上尝试 StrictMode 我注意到以下内容 并想知道这是否是我的应用程序或库中的问题 我不太清楚 谢谢你 D StrictMode StrictMode policy violation a
  • Android - 从资产中解析巨大(超大)JSON 文件的最佳方法

    我正在尝试从资产文件夹中解析一些巨大的 JSON 文件 我如何加载并添加到 RecyclerView 我想知道解析这种大文件 大约 6MB 的最佳方法是什么 以及您是否知道可以帮助我处理此文件的良好 API 我建议您使用GSON lib h
  • CardView 圆角获得意想不到的白色

    When using rounded corner in CardView shows a white border in rounded area which is mostly visible in dark environment F
  • Android SIP 来电使用带有广播接收器的服务

    大家好 其实我正在尝试创建一个应用程序 支持基于 SIP 通过互联网进行音频呼叫 这里使用本机 sip 我遇到了来电问题 我已经完成了服务的注册部分 但是在接听电话时我无法接听电话 请帮助我 Service file package exa
  • 在 HTTPResponse Android 中跟踪重定向

    我需要遵循 HTTPost 给我的重定向 当我发出 HTTP post 并尝试读取响应时 我得到重定向页面 html 我怎样才能解决这个问题 代码 public void parseDoc final HttpParams params n
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 在gradle插件中获取应用程序变体的包名称

    我正在构建一个 gradle 插件 为每个应用程序变体添加一个新任务 此新任务需要应用程序变体的包名称 这是我当前的代码 它停止使用最新版本的 android gradle 插件 private String getPackageName
  • 获取当前 android.intent.category.LAUNCHER 活动的实例

    我创建了一个库项目 并在多个应用程序之间共享 我实现了一个简单的会话过期功能 该功能将在一段时间后将用户踢回到登录屏幕 登录屏幕活动是我的主要活动 因此在清单中它看起来像这样
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 我想实现下面的布局,按钮应该在屏幕底部,当惰性列被填充时,按钮不应该出去

    顶部有惰性列 惰性列下方有输入电话号码布局并从电话簿布局添加联系人 我希望当未添加联系人时此布局位于顶部 当我添加大量联系人时输入电话号码并添加电话簿布局中的联系人会随着惰性列滚动并移出屏幕 我不让他们走出屏幕 当接触较多时 它们必须粘在底
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • 字符串数组文本格式化

    我有这个字符串 String text Address 1 Street nr 45 Address 2 Street nr 67 Address 3 Street nr 56 n Phone number 000000000 稍后将被使用
  • 如何根据 gradle 风格设置变量

    我想传递一个变量test我为每种风格设置了不同的值作为 NDK 的定义 但出于某种原因 他总是忽略了最后味道的价值 这是 build gradle apply plugin com android library def test andr
  • Android 套接字和 asynctask

    我即将开始制作一个应该充当 tcp 聊天客户端的应用程序 我一直在阅读和阅读 我得出的结论是最好 如果不需要 将我的套接字和异步任务中的阅读器 问题是我不确定从哪里开始 因为我是 Android 新手 这至少对我来说是一项艰巨的任务 但据我
  • Android:膨胀布局时出现 StackOverFlowError 和 InvokingTargetException

    首先 对不起我的英语 我在膨胀布局时有一个问题 我有一个自定义视图 从 LinearLayout 扩展而来 称为按钮帮助 我在名为的布局上使用该视图加载活动 我的以下代码在所有设备和模拟器上都能完美运行 但具有 QVGA 屏幕 例如 Sam
  • UDP SocketException - 通常只允许每个套接字地址使用一次

    尽管这里有很多非常相似的问题 但提供的答案都没有帮助我 这让我很难过 我有一个非常大的管理系统 我的任务是为其编写一些 UDP 数据包发送 接收 我已经编写了一个原型 一切都很好 所以我开始将我的代码合并到所述系统中 然而 我现在弹出了一个
  • Crashlytics 出现 Android Studio 构建错误

    我正在尝试将 CrashLytics 与 Android Studio 和 gradle 一起使用 但出现一个令人困惑的错误 java lang NoSuchMethodError 我的 build gradle 是 buildscript

随机推荐