#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];
, а затем прочитать в этом буфере likeint nread = input.read(buffer, 0, buffer.length);
.4. Еще раз спасибо @greenapps. Но тогда у меня есть int, и я ищу byte[] в моей переменной serverMessage. Как я могу этого добиться? Извините, если это глупый вопрос, но я новичок в этом.
5. Весь этот байтовый буфер, конечно, теперь заполнен … байтами. Это целое число nread` сообщает вам только о том, сколько байтов прочитано. Сколько байтов сейчас
buffer
.