将Float数据发送到我的客户端应用程序

时间:2018-02-26 16:06:11

标签: java c sockets floating-point

我用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);
}

}

我对于为了使bytebuffer工作而应该改变的内容非常困惑,并且不确定我是否正确地更改了它。 谢谢!

3 个答案:

答案 0 :(得分:1)

下定决心。

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

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

不是两者的混合物。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

当将float作为二进制数据,字节传输时,我会假设msg.obj实际上是一个字节数组。当浮点数从Intel小端平台发送为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可以破坏二进制数据。