TCP-клиент: получать байты из TCP-соединения — Java, Android

#java #android #tcp #client #bufferedinputstream

#java #Android #tcp #клиент #bufferedinputstream

Вопрос:

Я разрабатываю приложение для Android, которое получает некоторые данные с сервера. Я использовал этот учебник для TCP-клиента: учебник по TCP

В отличие от руководства, мне нужны данные в виде byte[], а не в виде строки, но я не могу понять, как это сделать.

Мой TCP-клиент:

 public class TCPClient {

private OnMessageReceived mMessageListener = null;
private BufferedInputStream input;
private byte[] serverMessage; // message received from server

private boolean mRun = false;

/**
 *  Constructor:
 *  OnMessagedReceived listens for the messages received from server.
 */
public TCPClient(OnMessageReceived listener) {
    mMessageListener = listener;
}

/**
 * Connection thread
 */
public void run() {
    mRun = true;

    try {
        // Server address:
        InetAddress serverAddr = InetAddress.getByName(10.0.0.170);

        Log.e("TCP Client", "C: Connecting...");

        // Connection socket:
        Socket socket = new Socket(serverAddr, 4848);

        try {
            // Input stream from server:
            input = new BufferedInputStream(socket.getInputStream());

            // Listen for messages from server:
            while (mRun) {
                int bytesRead = input.read();
                serverMessage = new byte[bytesRead];

                if (serverMessage != null amp;amp; mMessageListener != null) {
                    mMessageListener.messageReceived(serverMessage);
                }

                serverMessage = null; // reset serverMessage
            }
        } catch (Exception e) {
            Log.e("TCP", "S: Error", e);
        } finally {
            socket.close();
        }
    } catch (Exception e) {
        Log.e("TCP", "C: Error", e);
    }
}

public void stopClient(){
    mRun = false;
}

/**
 * The method messageReceived(byte[] message) must be implemented in the
 * MainActivity class at on asynckTask doInBackground
 */
public interface OnMessageReceived {
    public void messageReceived(byte[] message);
}

}
  

Основная деятельность:

 public class MainActivity extends AppCompatActivity {

// TCP Connection:
private TCPClient mTcpClient;
connectTask mConnectTask;

Button connectBtn;

// Debugging variable:
private static final String TAG = MainActivity.class.getName();

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

    // Relate Button and EditText from java to the one in XML:
    connectBtn = (Button) findViewById(R.id.connectBtn);

    mConnectTask = new connectTask(); // prepare for TCP connection

    // Connect to Server after connect btn pressed
    connectBtn.setOnClickListener(
            new View.OnClickListener() {
                public void onClick(View view) {
                    Log.i(TAG, "Connect button pressed.");
                    mConnectTask.execute(); // starts Async task
                }
            }
    );
}

public class connectTask extends AsyncTask<byte[], byte[], TCPClient> {

    @Override
    protected TCPClient doInBackground(byte[]... message) {

        // Create a TCPClient object
        mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {

            @Override
            // Implementation of messageReceived method
            public void messageReceived(byte[] message) {
                publishProgress(message); // calls the onProgressUpdate method
            }

        });

        mTcpClient.run();
        return null;
    }

    @Override
    protected void onProgressUpdate(byte[]... values) {
        super.onProgressUpdate(values);

        byte b[] = values[0];

        // TODO delete
        String str = new String(b, Charset.forName("UTF-8"));
        Log.d(TAG, "Data received: "   str);

        for (int i = 0; i < b.length; i  ) {
            int c = b[i] amp; 0xFF;
            Log.d(TAG, "c: "   c);

            // Further processing where data is needed as byte[]

        }
    }
}
}
  

Журнал.d

 Log.d(TAG, "Data received: "   str);
  

выходит из системы, что данные (неузнаваемые байты) получены. Но когда я выхожу из c, который должен быть полученным байтом в качестве int, он всегда равен 0.

Любая помощь приветствуется 🙂

Комментарии:

1. serverMessage = new byte[bytesRead]; . Таким образом, вы создаете байтовый буфер. Этот буфер заполняется случайным образом или заполняется случайным образом. Вы ничего не читаете в этот буфер. А затем вы его выбрасываете. .read() будет считан только один байт. Таким образом, ваши сообщения не могут быть длиннее 255 байт.

2. Спасибо @greenapps. Я не нашел правильного способа заменить метод readline() на байт [] . Можете ли вы подсказать мне метод или способ, который я мог бы использовать вместо этого?

3. Вы должны объявить байтовый буфер like byte buffer[2048]; , а затем прочитать в этом буфере like int nread = input.read(buffer, 0, buffer.length); .

4. Еще раз спасибо @greenapps. Но тогда у меня есть int, и я ищу byte[] в моей переменной serverMessage. Как я могу этого добиться? Извините, если это глупый вопрос, но я новичок в этом.

5. Весь этот байтовый буфер, конечно, теперь заполнен … байтами. Это целое число nread` сообщает вам только о том, сколько байтов прочитано. Сколько байтов сейчас buffer .