【问题标题】:Sending Float data to my client application将浮点数据发送到我的客户端应用程序
【发布时间】:2018-08-06 03:26:40
【问题描述】:

我用 C 编写了一段服务器代码,我想在每次迭代时将数据连续发送到我的客户端应用程序。

while (1)
{
    startInt = mymillis();//capture starting time

    Sensor_raw_data_float = Sensor_Read_Values_();
    float data = Sensor_raw_data_float.x * 0.007;

    send(sockfd, &data , sizeof(float),0);//Send to client

    //Wait until 5ms
    while (mymillis() - startInt < (5))
    {
        usleep(100);
    }

}

我尝试在发送之前使用“snprintf”将我的浮点数据转换为字符串,但我意识到整个系统开始变慢并且滞后很多。

因此,我尝试对客户端代码进行编辑。附件是我的客户端代码的主要部分,与我正在尝试做的事情有关

    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

EditText editTextAddress, editTextPort, editTextMsg;
Button buttonConnect, buttonDisconnect, buttonSend;
TextView textViewState, textViewRx;

ClientHandler clientHandler;
ClientThread clientThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

textViewRx = (TextView) findViewById(R.id.received);

    clientHandler = new ClientHandler(this);
}

private void updateState(String state){
    textViewState.setText(state);
}

private void updateRxMsg(String rxmsg){
    textViewRx.append(rxmsg + "\n");

}


public static class ClientHandler extends Handler {
    public static final int UPDATE_STATE = 0;
    public static final int UPDATE_MSG = 1;
    public static final int UPDATE_END = 2;
    private MainActivity parent;

    public ClientHandler(MainActivity parent) {
        super();
        this.parent = parent;
    }

    @Override
    public void handleMessage(Message msg) {

        switch (msg.what){
            case UPDATE_STATE:
                parent.updateState((String)msg.obj);
                break;
            case UPDATE_MSG:
                parent.updateRxMsg((String)msg.obj);
                break;
            case UPDATE_END:
                parent.clientEnd();
                break;
            default:
                super.handleMessage(msg);
        }

    }

}

}

我尝试将 updateRxMsg(String rxmsg) 的代码编辑为

 private void updateRxMsg(String rxmsg){
    private void updateRxMsg(String rxmsg){
    //textViewRx.append(rxmsg + "\n");
    float f = Float.parseFloat(rxmsg);
    String mytext=Float.toString(f);
    textViewRx.append(mytext + "\n");
}

}

但我仍然在我的 TextView 上打印出垃圾。我无法弄清楚问题是什么,但我怀疑它与编码有关。我想就如何将我的浮动数据从我的服务器获取到我的客户端获得一些帮助。

更新:附件是我的缓冲区阅读器等的代码,最初我认为问题不在于这里,但我也会在这里发布。

public class ClientThread extends Thread{

String dstAddress;
int dstPort;
private boolean running;
MainActivity.ClientHandler handler;

Socket socket;
PrintWriter printWriter=null;
BufferedReader bufferedReader;

public ClientThread(String addr, int port, MainActivity.ClientHandler handler) {
    super();
    dstAddress = addr;
    dstPort = port;
    this.handler = handler;
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
            .permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

public void setRunning(boolean running){
    this.running = running;
}

private void sendState(String state){
    handler.sendMessage(
            Message.obtain(handler,
                    MainActivity.ClientHandler.UPDATE_STATE, state));
}

public void txMsg(String msgToSend){
    if(printWriter != null){
        printWriter.println(msgToSend);
    }
}

@Override
public void run() {
    sendState("connecting...");

    running = true;

    try {
        socket = new Socket(dstAddress, dstPort);
        sendState("connected");

        OutputStream outputStream = socket.getOutputStream();
        printWriter = new PrintWriter(outputStream, true);

        InputStream inputStream = socket.getInputStream();
        InputStreamReader inputStreamReader =
                new InputStreamReader(inputStream);
        bufferedReader = new BufferedReader(inputStreamReader);

        while(running){

            //bufferedReader block the code
            String line = bufferedReader.readLine();
            if(line != null){
                handler.sendMessage(
                        Message.obtain(handler,
                                MainActivity.ClientHandler.UPDATE_MSG, line));
            }

        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(bufferedReader != null){
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(printWriter != null){
            printWriter.close();
        }

        if(socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    handler.sendEmptyMessage(MainActivity.ClientHandler.UPDATE_END);
}

}

我将代码更新为:

import android.os.Message;
import android.os.StrictMode;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.ByteBuffer;

公共类 ClientThread 扩展线程{

String dstAddress;
int dstPort;
private boolean running;
MainActivity.ClientHandler handler;

Socket socket;
PrintWriter printWriter=null;
BufferedReader bufferedReader;

public ClientThread(String addr, int port, MainActivity.ClientHandler handler) {
    super();
    dstAddress = addr;
    dstPort = port;
    this.handler = handler;
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
            .permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

public void setRunning(boolean running){
    this.running = running;
}

private void sendState(String state){
    handler.sendMessage(
            Message.obtain(handler,
                    MainActivity.ClientHandler.UPDATE_STATE, state));
}

public void txMsg(String msgToSend){
    if(printWriter != null){
        printWriter.println(msgToSend);
    }
}

@Override
public void run() {
    sendState("connecting...");

    running = true;

    try {
        socket = new Socket(dstAddress, dstPort);
        sendState("connected");

        OutputStream outputStream = socket.getOutputStream();
        printWriter = new PrintWriter(outputStream, true);

        InputStream inputStream = socket.getInputStream();
        InputStreamReader inputStreamReader =
                new InputStreamReader(inputStream);
        bufferedReader = new BufferedReader(inputStreamReader);

        int bufferSize = 8192;

        ByteBuffer bf = ByteBuffer.allocate(bufferSize);
            BufferedInputStream inFromServer = new BufferedInputStream(socket.getInputStream());
            while (true) {
                int b = inFromServer.read();
                if (b == -1) {
                    break;
                }
                bf.put( (byte) b);

                handler.sendMessage(
                        Message.obtain(handler,
                                MainActivity.ClientHandler.UPDATE_MSG, (byte) b));
            }

       // while(running){

            //bufferedReader block the code
        //    String line = bufferedReader.readLine();
       //     if(line != null){
       //         handler.sendMessage(
       //                 Message.obtain(handler,
       //                         MainActivity.ClientHandler.UPDATE_MSG, line));
      //      }

      //  }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(bufferedReader != null){
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if(printWriter != null){
            printWriter.close();
        }

        if(socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    handler.sendEmptyMessage(MainActivity.ClientHandler.UPDATE_END);
}

}

我很困惑应该更改哪些内容才能使字节缓冲区正常工作,并且不确定我是否正确更改了它。 谢谢!

【问题讨论】:

    标签: java c sockets floating-point


    【解决方案1】:

    作为一种解决方法,我建议您在发送之前尝试将浮点数转换为整数(只需乘以 10 到您想要的精度的幂)并查看您获得的数据。这可以帮助你缩小问题的范围。如果你真的坚持使用浮点数你可能想参考这个问题:How are floating point numbers are stored in memory?

    【讨论】:

      【解决方案2】:

      当将浮点数作为二进制数据字节传输时,我会假设 msg.obj 实际上是一个字节数组。当浮点数从 Intel little endian 平台以 4 个字节发送时,以下代码应该可以工作。

             case UPDATE_MSG:
                  byte[] flt = (byte[])msg.obj;
                  if (flt.length != 4) {
                      throw new IllegalStateException();
                  }
                  float x = ByteBuffer.wrap(flt)
                      .order(ByteOrder.LITTLE_ENDIAN)
                      .getFloat();
                  break;
      

      由于您没有收到 ClassCastException,我仍然有一些疑问。 但是,二进制数据不能由内部使用 Unicode 的字符串保存,如 UTF-16,这可能会损坏二进制数据。

      【讨论】:

      • 嗨 Joop eggen,我试过你的代码,应用程序在启动时立即崩溃。是因为我使用的是字符串而不是字节吗?我刚刚用包含 bufferedReader 的代码更新了我的帖子。浮点数是从 ARMs linux 机器发送的。
      【解决方案3】:

      下定决心。

      如果您直接发送float,请按照您发布的代码,使用DataInputStream.readFloat() 阅读。如果你很幸运并且字节顺序相同,那么你就完成了。

      或者将其转换为字符串,作为一行发送,作为一行读取,然后解析回float

      不是两者的混合体。

      【讨论】:

      • 嗨 EJP,是的,你是对的,我直接发送浮点数。我尝试了您提到的第二种方法,但是我的服务器变得非常滞后。如果您指导我如何编辑我的代码以使用 DataInputStream.readFloat(),可以吗?我不确定要进行哪些必要的更改。
      • 嗯?创建一个DataInputStream,并在其上调用readFloat()。没有什么神秘的。
      猜你喜欢
      • 2010-11-15
      • 2012-10-19
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多