2012-05-24 18 views
1

Я пытаюсь получить клиент C99 для связи с сервером Java. Однако данные, принимаемые сервером Java, не совпадают с данными, которые были переданы. (т. е. @ x @ Ó fl/ú. @¨ Û¢ÁBp'¡`Ô fl /)Клиент C99, взаимодействующий с Java-сервером

Я созерцал что это проблема с кодировкой, однако я ударил по кирпичной стене. Я пробовал тестировать две программы, чтобы сделать вывод, что сервер Java способен связываться с клиентом Java, а клиент C может связываться с сервером C.

Однако я не могу заставить сервер Java связываться с клиентом C.

Java-код: Код

serverSocket = new ServerSocket(port); 
Socket sock = serverSocket.accept();        

BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream())); 

String inputString = in.readLine(); 
System.out.println(inputString); 

C:

struct sockaddr_in sin; 
struct hostent *host; 

host = gethostbyname(hostname); 

bzero(&(sin.sin_zero),8); 
sin.sin_port = htons(port); 
sin.sin_addr = *((struct in_addr *)host->h_addr); 
sin.sin_family = AF_INET; 

sock = socket(AF_INET, SOCK_STREAM, 0); 

if(connect(sock, (struct sockaddr *)&sin,sizeof(struct sockaddr_in)) == -1) 

...

send(sock, &message, strlen(message)+1, 0); 

EDIT: Я пытался отправив слово 'TEST' между двумя хостов без успеха.

FIXED: У меня был амперсанд перед переменной сообщения, когда я проходил мимо него.

Должно быть:

send(sock, message, strlen(message)+1, 0); 
+0

Что такое кодирование сообщения от C? – nhahtdh

+0

Итак, мой ответ был правильным;) – Morpfh

ответ

2

Я не уверен, если C99 обеспечивает стандарт для кодирования, но я предполагаю, что это зависит от конкретной реализации. Например, это может быть US-ASCII.

Что происходит, так это то, что Java InputStreamReader (или вывод) использует кодировку по умолчанию, указанную где-то в ОС или в установке Java (не уверен, где), поэтому она может отличаться от той, которая используется программой C.

Самое лучшее, что вы можете сделать, это проверить различные кодировки, то InputStreamReader класс действительно предоставляет определенный конструктор:

public InputStreamReader(InputStream in, Charset cs) 

, в которых вы имеете право указать, какой набор символов вы хотите использовать. Посмотрите here для возможных кодировок.

+0

Клиент C использует кодировку US-ASCII в соответствии с nl_langinfo (CODESET), поэтому это не проблема с кодировкой символов. Я также заставил сервер Java использовать этот набор символов с помощью InputStreamReader без успеха. – Khronos

1

Вы также должны смотреть на несоответствие между собой: Java использует network order, в то время как хост C не может. ByteBuffer, иллюстрированный here, может помочь.

0

ваша проблема выглядит как выравнивание байта

в клиенте C вам нужно преобразовать хоста в сетевой порядок байт.

использование

uint32_t htonl(uint32_t hostlong); 

uint16_t htons(uint16_t hostshort); 

uint32_t ntohl(uint32_t netlong); 

uint16_t ntohs(uint16_t netshort); 
+0

Я отправляю текст, а не сырые цифры. – Khronos

+0

PLS ссылаются на этот вопрос для отправки массивов символов http://stackoverflow.com/q/526030/143897 –

+0

Отправка слова «тест» с клиента на сервер не сработала. В сообщении не было никаких цифр, поэтому я сомневаюсь, что это проблема. – Khronos

0

Если я не ошибается у вас есть что-то вроде:

char *message = "Hello"; 

Когда вы посылаете:

send(sock, &message, strlen(message)+1, 0); 
      | 
      +---- Err. 

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

Если вы сделаете это вместо:

send(sock, message, strlen(message)+1, 0); 

Он должен работать.

Или использовать char message[] = "Hello"; ...


Для дальнейшего рассекать сервера данных вы могли бы сделать что-то вроде:

 int i = 0; 
     for (char ch : inputString.toCharArray()) { 
      System.out.printf("%2d: 0x%02X o%03o %3d %c%n", 
       i++, 
       (int)ch & 0xff, 
       (int)ch & 0xff, 
       (int)ch & 0xff, 
       Character.isISOControl(ch) ? '.' : ch 
      ); 
     } 

или

 buf = inputLine.getBytes(/* charset */); 
     for (i = 0; i < buf.length; ++i) { 

т.д.

Client siad: Hello 
0: 0x00 o000 0 . 
1: 0x48 o110 72 H 
2: 0x65 o145 101 e 
3: 0x6C o154 108 l 
4: 0x6C o154 108 l 
5: 0x6F o157 111 o 

Использование & сообщение:

Client said: `� 
0: 0x60 o140 96 ` 
1: 0xEF o357 239 ￯ 
2: 0xBF o277 191 ﾿ 
3: 0xBD o275 189 ᄑ 
4: 0x04 o004 4 . 
5: 0x08 o010 8 . 

Другой хак/отладки/что можно сделать что-то вроде:

while (true) { 
     in.mark(128); 
     if ((inputLine = in.readLine()) == null) 
      continue; 

     System.out.println("Response: " + inputLine); 

     in.reset(); 
     i = 0; 
     while (in.ready()) { 
      c = in.read(); 
      System.out.printf("%2d: 0x%02X o%03o %3d %c%n", 
       i++, 
       c, c, c, 
       Character.isISOControl((char) c) ? '.' : (char)c 
      ); 
     } 
    }