Java TCP простое общение дает неожиданные результаты - PullRequest
2 голосов
/ 30 октября 2011

Я пытаюсь отправить некоторые простые данные по TCP в моей Java-программе:

         String data = "70798090999a9b9c9d9e9fa0a1a2";
             ServerSocket srvr = new ServerSocket(1234);
             Socket skt = srvr.accept();
             OutputStream out = skt.getOutputStream();
             out.write(hexStringToByteArray(data));
             out.close();
             skt.close();
             srvr.close();

С функцией:

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

и получить данные как:

     Socket skt = new Socket("localhost", 1234);
     BufferedReader in = new BufferedReader(new
        InputStreamReader(skt.getInputStream()));

     while (!in.ready()) {}
     while (in.ready()) {
     System.out.println(in.read()); // Read one line and output it
     }

Но вместо того, чтобы получать список чисел, которые обычно увеличиваются, я получаю что-то, что увеличивается и уменьшается по прихоти:

121
196
234
244
246
245
250
249
251
252
8224
176
162

Где я делаю что-то не так?

Ответы [ 3 ]

3 голосов
/ 30 октября 2011

Если вы хотите отправить байты, я предлагаю вам прочитать байты, если вы хотите отправить текст, я предлагаю вам прочитать текст. Вы не должны пытаться смешивать и сочетать, иначе вы запутаетесь.

byte[] bytes = new BigInteger("70798090999a9b9c9d9e9fa0a1a2", 16).toByteArray();

ServerSocket ss = new ServerSocket(1234);
Socket c = new Socket("localhost", 1234);
Socket s = ss.accept();
final OutputStream out = s.getOutputStream();
out.write(bytes.length);
out.write(bytes);

final DataInputStream in = new DataInputStream(c.getInputStream());
int length = in.read();
byte[] bytes2 = new byte[length];
in.readFully(bytes2);

System.out.println(new BigInteger(1, bytes2).toString(16));
c.close();
s.close();
ss.close();

печать

70798090999a9b9c9d9e9fa0a1a2
3 голосов
/ 30 октября 2011

Вы отправляете байтовый массив и читаете только один байт.

Вы должны читать, используя цикл, как показано ниже:

byte[] arr = new byte[1024];
while (in.read(arr) >= 0) {
    // do something with the data.
}

Это будет работать, но все же это не то, что вам действительно нужно. Действительно, вы работаете со строками, но затем вручную преобразуете строку в байтовый массив, а затем читаете байты, чтобы вручную снова преобразовать их в строку?

Вместо этого вы должны использовать PrintWriter для записи строк:

PrintWriter writer = new PrintWriter(new OutputStreamWriter(out));
writer.write(str);

, а затем используйте BufferedReader при чтении данных.

BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();
1 голос
/ 31 октября 2011

Избавьтесь от всех готовых () тестов. Чтения будут блокироваться до тех пор, пока не поступят данные, поэтому вызов метода ready () находится на пике буквально пустой тратой времени и рискует пропустить данные.

...