Estou construindo um sistema para fazer comunicação via Socket:
O sistema cliente envia as seguintes informações:
1 - int - tamanho da mensagem
2 - bytes - a mensagem
A mensagem é constituída por:
1 - int - código do método que quero executar no servidor
2 - int - tamanho da lista que quero enviar
3 - int - id da pessoa
4 - int - tamanho da string do nome da pessoa
5 - String - string do nome da pessoa
Os tópicos 3, 4 e 5 são executados para cada item da lista
Meu sistema cliente fica assim:
private void btComunicarActionPerformed(java.awt.event.ActionEvent evt) {
List<PessoaMOD> pessoas = new ArrayList<PessoaMOD>();
pessoas.add(new PessoaMOD(1, "Pessoa 1"));
pessoas.add(new PessoaMOD(2, "Pessoa 2"));
pessoas.add(new PessoaMOD(3, "Pessoa 3"));
pessoas.add(new PessoaMOD(4, "Pessoa 4"));
pessoas.add(new PessoaMOD(5, "Pessoa 5"));
pessoas.add(new PessoaMOD(6, "Pessoa 6"));
pessoas.add(new PessoaMOD(7, "Pessoa 7"));
pessoas.add(new PessoaMOD(8, "Pessoa 8"));
try {
Socket cliente = new Socket("127.0.0.1", 12345);
enviarMensagem(codificarListarPessoas(pessoas), cliente);
} catch (Exception e) {
System.out.println("Erro: " + e.getMessage());
} finally {
}
}
public ByteArrayOutputStream codificarListarPessoas(List<PessoaMOD> pessoas) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeByte(1); //Método 1, gravar pessoas
dos.writeInt(pessoas.size()); // tamanho da lista
for (PessoaMOD p : pessoas) {
dos.writeInt(p.getId()); // id da pessoa
dos.writeInt(p.getNome().length()); //Nr de caracteres do nome da pessoa
dos.writeChars(p.getNome()); //Nome da pessoa
}
return bos;
}
public void enviarMensagem(ByteArrayOutputStream mensagem, Socket socket) throws IOException {
byte[] msg = mensagem.toByteArray();
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(msg.length); //O tamanho da mensagem
out.write(msg); //Os dados
out.flush();
}
Minha dúvida é de ler isto no servidor:
Estou fazendo assim no servidor:
private void btIniciarActionPerformed(java.awt.event.ActionEvent evt) {
new Thread() {
@Override
public void run() {
try {
ServerSocket servidor = new ServerSocket(12345);
System.out.println("Servidor ouvindo a porta 12345");
while (true) {
Socket cliente = servidor.accept();
System.out.println("Cliente conectado: " + cliente.getInetAddress().getHostAddress());
DataInputStream entrada = new DataInputStream(cliente.getInputStream());
int tamanhoMsg = entrada.readInt(); // ler tamanho da mensagem
// leio os bytes de acordo com o
//tamanho da mensagem lida anteriormente
byte[] bytes = new byte[tamanhoMsg];
int op = entrada.read(bytes, 0 , bytes.length);
// Como posso fazer a leitura separada dos dados enviados?
entrada.close();
cliente.close();
}
} catch (Exception e) {
System.out.println("Erro: " + e.getMessage());
} finally {
}
}
}.start();
}
Li o tamanho da mensagem e recebi todos os bytes de acordo com o tamanho enviado.
Mas agora como posso separar esses bytes de acordo com os dados que enviei, ou seja, separar tamanho da lista, id, tamanho da string, string do nome.
-----------------EDIT---------------
Tentei fazer enviando um JSON, mas dá erro
Quando o Json é muito grande, há perda de parte da String, envio assim:
private void btComunicarActionPerformed(java.awt.event.ActionEvent evt) {
List<PessoaMOD> pessoas = new ArrayList<PessoaMOD>();
for (int i = 1; i <= 2000; i++) {
pessoas.add(new PessoaMOD(i, "Pessoa " + i));
}
try {
Socket cliente = new Socket("127.0.0.1", 12345);
enviarMensagem(codificarListarDiretorio(pessoas), cliente);
} catch (Exception e) {
System.out.println("Erro: " + e.getMessage());
} finally {
}
}
public ByteArrayOutputStream codificarListarDiretorio(List<PessoaMOD> pessoas) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
Gson gson = new GsonBuilder().create();
dos.write(gson.toJson(pessoas).getBytes());
return bos;
}
public void enviarMensagem(ByteArrayOutputStream mensagem, Socket socket) throws IOException {
byte[] msg = mensagem.toByteArray();
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeInt(msg.length); //O tamanho da mensagem
out.write(msg); //Os dados
out.flush();
String s;
}
e recebo assim:
int tamanhoMsg = entrada.readInt();
byte[] bufferJson = new byte[tamanhoMsg];
entrada.read(bufferJson, 0, bufferJson.length);
String json = new String(bufferJson);
Só que a String do Json não chega completa quando é muito grande.
O que acontece é que o numero de bytes é maior do que o lenght suporta, então o tamanho da mensagem não envia completo…
Também tentei enviar pelo método writeUTF();
Mas como a String é grande, gera esse erro: encoded string too long: 677789 bytes