使用Telnet正确读取行

时间:2014-12-31 18:07:43

标签: java android telnet

我有一个Android应用,应该接收和阅读NMEA句子

  

e.g。 $ GPGLL,3751.65,S,14507.36,E * 77

使用Telnet协议从远程TCP-Server。我正在使用org.apache.commons.net.telnet.TelnetClient库。

什么有效:

  • 连接服务器

  • 阅读一些句子,没有任何错误

问题: 有一半以上的句子丢失了。我想这是一个计时问题,也许这也与在每次迭代中重新启动的连接有关。

这是我的MainActivity.java

package com.example.clienttel;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import org.apache.commons.net.telnet.TelnetClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Go to ClientThread, where NMEA-sentences will be received
        int i;
        for (i = 0; i < 10000; i++)     // 10000 for testing
            new Thread(new ClientThread()).start();
    }

    class ClientThread implements Runnable {
        //@Override
        public void run() {
            TelnetClient telnet = new TelnetClient();

            // Variables
            String ADDRESS = "194.66.82.11";
            int PORT = 51000;
            String NMEA = null;
            final String TAG = "TestApp";

            // Connect To Server
            try {
                telnet.connect(ADDRESS, PORT);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // Process NMEA-sentences
            InputStream inStream = telnet.getInputStream();
            BufferedReader r = new BufferedReader(new InputStreamReader(inStream));

            try {
                NMEA = r.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            // Ignore "...busy" sentences
            if (NMEA != null) {
                if(!(NMEA.equals("*** Serial port is busy ***"))) {
                    Log.i(TAG, NMEA);
                }
            }

            // Disconnect From Server
            try {
                telnet.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

任何帮助将不胜感激!

修改

我的代码现在看起来像这样:

package com.example.clienttel;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;

import org.apache.commons.net.telnet.TelnetClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class MainActivity extends ActionBarActivity {
    // Variables
    public String ADDRESS = "194.66.82.11";
    public int PORT = 50100;
    public String NMEA = null;
    public final String TAG = "TestApp";
    public boolean first = true;


    // Handler in mainthread
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            String dataString = "";
            Bundle bundle = msg.getData();

            Log.d("handleMessage", bundle.toString());
            if (bundle.containsKey("outgoingString")) {
                dataString = bundle.getString("outgoingString");
            }
        }
    };

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

        ClientThread ct;
        ct = new ClientThread();
        ct.mhandler=handler;

        int i;
        for (i = 0; i < 10000; i++) {     // 10000 for testing
            // Go to ClientThread, where NMEA-sentences will be received
            //new Thread(new ClientThread()).start();
            ct.start();
        }
    }

    class ClientThread implements Runnable {
        public Handler mhandler = null;
        @Override
        public void run() {
            TelnetClient telnet = new TelnetClient();

            if (first) {
                // Connect To Server in 1st Iteration
                try {
                    telnet.connect(ADDRESS, PORT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                first = false;
            }

            // Process NMEA-sentences
            InputStream inStream = telnet.getInputStream();
            BufferedReader r = new BufferedReader(new InputStreamReader(inStream));

            try {
                NMEA = r.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            // Handler in ClientThread to send back
            Bundle b = new Bundle();

            b.putString("outgoingString", NMEA);

            Message m = mhandler.obtainMessage();
            m.setData(b);
            mhandler.sendMessage(m);
        }
    }
}

但我不确定处理程序的位置

1 个答案:

答案 0 :(得分:3)

正如@EJP所说,打开关闭每一行的连接会杀死该应用......

更好的方法是让线程处理通信并等待下一行,将数据作为bundle消息传递回主线程。

有很多例子,但基本上你在主线程中创建了一个处理程序:

Handler handler = new Handler()
{
    public void handleMessage(Message msg)
    {

        String dataString = "";

        Bundle bundle = msg.getData();

        Log.d("handleMessage", bundle.toString());
        if (bundle.containsKey("outgoingString"))
        {
            dataString = bundle.getString("outgoingString");

        }

        // you can handle other message types here....
   }

并将它(处理程序)传递给您的ClientThread(此处为mhandler),您可以在其中发送消息:

Bundle b = new Bundle();

b.putString("outgoingString", outgoingText);
Message m = mhandler.obtainMessage();
m.setData(b);
mhandler.sendMessage(m);