Моя проблема заключается в том, как получить данные из примера сервера «разрезание» в посылки 1024 байта, потому что, когда ответ приходит от сервера в пакетах, таких как 2 части, я не знаю, как это решить. Пример. Когда первый пакет поступает, размер, сообщенный сервером, равен 1988 году, а принятое значение равно 1444, что все в порядке, но когда второй пакет поступает, информированный размер является чем-то вроде 808333347 и получил 540, сумма 1444 + 540 = 1984, которая права , Я не знаю, откуда этот номер 808333347. Я ищу Google для этого решения, и все они учатся с помощью udp, и мне это нужно для подключения tcp/ip. Пожалуйста, помогите мне, решите это.Java nio read bytebuffer из канала
Класс:
public class Connection implements Runnable {
private static Connection instance;
private SocketChannel channel = null;
private int port = 0;
private int service = 0;
private final int SOCKET_TIMEOUT = 15 * 1000;
private final int SOCKET_BYTES = 16 * 1024;
private final Charset CHARSET = Charset.forName("ISO-8859-1");
private String host = null;
private String message = "";
public Connection(String host, String port){
this.host = host;
this.port = Integer.parseInt(port);
}
public static Connection createConnection(String host, String port) {
if(instance == null){
instance = new Conexao(host, port);
}
return instance;
}
public void connect(){
try{
instance.channel = SocketChannel.open();
instance.channel.socket().setSoTimeout(SOCKET_TIMEOUT);
instance.channel.socket().setTcpNoDelay(false);
instance.channel.socket().setKeepAlive(true);
instance.channel.connect(new InetSocketAddress(host, port));
instance.channel.configureBlocking(false);
} catch (IOException ioe){
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
}
@Override public void run() {
if(null != instance.channel){
if(instance.channel.isConnected()){
Log.d(TAG, "CHANNEL CONNECTED = TRUE");
} else {
Log.d(TAG, "CHANNEL CONNECTED = FALSE");
}
} else {
instance.connect();
Log.d(TAG, "CHANNEL CONNECTED");
}
sendMessage();
while(true){
receiveMessage();
}
}
public void sendMessage() {
int size = message.length();
ByteBuffer buffer = ByteBuffer.allocate(4 + 4 + size);
buffer.putInt(service).putInt(size).put(message.getBytes());
buffer.flip();
for(int i = 0; i < size; i++){
try {
instance.channel.write(buffer);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
}
}
public void receiveMessage(){
ByteBuffer buffer = ByteBuffer.allocateDirect(SOCKET_BYTES);
int bytesReaded = 0;
String received = "";
buffer.clear();
try {
do {
bytesReaded = instance.channel.read(buffer);
} while (bytesReaded == 0);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
buffer.flip();
int size = buffer.getInt();
received += CHARSET.decode(buffer);
Log.d(TAG,"SERVIÇE: " + size + "/" + received.length() + " MSG: " + received);
}
public int getService() {
return service;
}
public void setService(int service) {
this.service = service;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
Я изменил функцию так:
public void receiveMessage(){
ByteBuffer buffer = ByteBuffer.allocateDirect(SOCKET_BYTES);
int bytesReaded = 0;
String received = "";
buffer.clear();
try {
bytesReaded = instance.channel.read(buffer);
} catch (IOException ioe) {
Log.d(TAG, ioe.getMessage() + " " + ioe.toString());
}
buffer.flip();
if(bytesReaded >= 4){
if(size == 0 && size < 5000) size = buffer.getInt();
received += CHARSET.decode(buffer);
answer += received;
if(size == answer.length()){
Log.d(TAG,"SERVICE: " + size + "/" + answer.length() + " " + answer);
}
}
}
Но это очень некрасиво прямо сейчас.
Я понял и решил проблему накопления данных, теперь все в порядке, но вопрос о размере, первый размер, который поступает с сервера, прав, как я могу его синхронизировать? –
Убедитесь, что вы точно прочитали количество байтов сообщений, указанное словом размера. В противном случае вы будете неправильно понимать следующие слова службы/размера. – EJP