【问题标题】:Non-updating socket message非更新套接字消息
【发布时间】:2020-06-22 14:05:25
【问题描述】:

我一直在研究我的 Raspberry Pi 和我的手机之间的连接,为了完成它,我想使用套接字。 凭借我最少量的经验,我在互联网上四处搜寻,试图找到我的 Pi (C++) 的套接字代码和我的手机 (Java) 的 Android 应用程序。两者都包含在下面。

我遇到的问题是,当从 C++ 服务器发送新消息时,我手机上的文本框没有更新。我相信我用 C++ 编写的代码很好。它所要做的就是不断要求用户提供新的输入以发送给客户端。

我相信问题出在我手机的 Java 应用程序中。

我完全不知道自己在做什么,我希望这里的人能用简单的语言向我解释发生了什么(或者更确切地说是什么没有发生)。

提前谢谢你!

C++ 服务器代码:

#include <iostream>
#include <boost/asio.hpp>

using namespace boost::asio;
using ip::tcp;
using std::string;
using std::cout;
using std::endl;

string read_(tcp::socket & socket)
{
boost::asio::streambuf buf;
boost::asio::read_until(socket, buf, "\n" );
string data = boost::asio::buffer_cast<const char*>(buf.data());
return data;
}

void send_(tcp::socket & socket, const string& message)
{
const string msg = message + "\n";
boost::asio::write(socket, boost::asio::buffer(message));
}

int main()
{
boost::asio::io_service io_service;

tcp::acceptor acceptor_(io_service, tcp::endpoint(tcp::v4(), 41517));

tcp::socket socket_(io_service);

acceptor_.accept(socket_);
/*
string message = read_(socket_);
cout << message << endl;
*/
send_(socket_, "Hello from server!\n");
cout << "Server sent hello message to Client!" << endl;

char message[400];

while(true)
{
std::cin.getline(message, 400);
string messageStr = message;

if(messageStr.length() > 0)
{
send_(socket_, messageStr);
cout << "The following message has been sent:" << endl << endl;
cout << messageStr << endl << endl << "-----------------------------" << endl << endl;
}

else
{
cout << "No message has been sent." << endl << endl << "-----------------------------" << endl << endl;
}
}

return 0;
}

Java 客户端代码

package com.example.socket_test2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.SocketAddress;

import static java.lang.Integer.parseInt;

public class MainActivity extends AppCompatActivity {

    TextView responseField;
    EditText ipField, portField;
    Button randomButton;

    ConnectionMaker juin = new ConnectionMaker();

    Socket sock = new Socket();

    BufferedReader br;

    private class ConnectionMaker extends AsyncTask<String, Integer, Integer> {
        @Override
        protected Integer doInBackground(String... strings) {

            try {
                SocketAddress addr = new InetSocketAddress(strings[0], parseInt(strings[1]));
                sock.connect(addr);

                br = new BufferedReader(new InputStreamReader(sock.getInputStream()));

                while(true) {
                    responseField.setText(br.readLine());
                }

                //sock.close();
            } catch (Exception ex) {
                responseField.setText(ex.getLocalizedMessage());
            }



            return 1;
        }
    }

    View.OnClickListener action = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            try{
                juin.execute(ipField.getText().toString(), portField.getText().toString());
            } catch (Exception ex) {
                responseField.setText(ex.getLocalizedMessage());
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        responseField = findViewById(R.id.ResponseField);
        randomButton = findViewById(R.id.RandomButton);

        ipField = findViewById(R.id.IP_Field);
        portField = findViewById(R.id.Port_Field);

        randomButton.setOnClickListener(action);
    }
}

【问题讨论】:

  • send_(socket_, messageStr); 那应该是send_(socket_, messageStr+"\n"); 客户端尝试读取行,因此服务器应该发送行。
  • 即使 send_() 函数有 +"\n"?
  • 没有。对不起,监督了。
  • 您的客户只阅读行。不向服务器发送任何线路。只有服务器发送的第一行进入。此外,服务器不发送任何行。只有当服务器断开空行时,客户端才会读取。
  • 所以服务器的while(true)循环永远不会发送一行。

标签: java android c++ sockets


【解决方案1】:

AsyncTaskdoInBackground 方法不在 UI 线程上运行,因此您不能在那里调用responseField.setText。或者更确切地说:您可以调用它,但不保证 UI 线程可以看到它。

改为使用publishProgress,它的onProgressUpdate处理程序在UI线程上被调用:

private class ConnectionMaker extends AsyncTask<String, String, Integer> {
    @Override
    protected Integer doInBackground(String... strings) {

        try {
            SocketAddress addr = new InetSocketAddress(strings[0], parseInt(strings[1]));
            sock.connect(addr);

            br = new BufferedReader(new InputStreamReader(sock.getInputStream()));

            while(true) {
                publishProgress(br.readLine());
            }

            //sock.close();
        } catch (Exception ex) {
            responseField.setText(ex.getLocalizedMessage());
        }

        return 1;
    }

    @Override
    protected void onProgressUpdate(String... progress) {
        responseField.setText(progres[0]);
    }
}

【讨论】:

  • 感谢您的回复!我尝试实施您的解决方案,但没有奏效。然而,我确实发现每当我停止我的 C++ 代码时,文本框就会被清空。你知道这意味着什么吗?
  • 我不确定这是否有助于解决问题,但无论如何我还是要表示感谢!感谢您帮助@Botje!
猜你喜欢
  • 1970-01-01
  • 2021-05-16
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
相关资源
最近更新 更多