2016-11-03 2 views
1

У меня есть следующая проблема:C-сервер становится неправильно Packet

  • У меня есть Java-клиент с помощью рамки Apache Mina отправить строку.
  • Я написал сервер C для получения строки.
  • Итак, я попытался отправить utf8 символ сервера: myStringToSend = «А»
  • Я отлажен источнику Mina, чтобы увидеть пакет в байте или шестнадцатеричные и Мину преобразовать строку, так что он послал 0xC30x84 ,
  • Я также проверяю отправленный пакет в wirecark network viewer, и он также видит 0xC30x84 как пакет, все в порядке.
  • Но мой C-сервер получает следующие байты: FFFFFFC3FFFFFF84

Я не знаю, что происходит не так?

код моего C-сервера:

#include "stdafx.h" 
#include <io.h> 
#include <stdio.h> 
#include <winsock2.h> 

#pragma comment(lib,"ws2_32.lib") //Winsock Library 

#define DEFAULT_BUFLEN 512 
#define TOOBIG 100000 

int main(int argc, char *argv[]) 
{ 
WSADATA wsa; 
int i, c, iResult, iSendResult, outputCounter; 

SOCKET listenSocket = INVALID_SOCKET, clientSocket = INVALID_SOCKET; 
struct sockaddr_in server, client; 
char *message; 

char sendbuf[DEFAULT_BUFLEN]; 
unsigned char recvbuf[DEFAULT_BUFLEN]; 
int recvbuflen = DEFAULT_BUFLEN; 

printf("\nInitialising Winsock..."); 
if (WSAStartup(MAKEWORD(2,2),&wsa) != NO_ERROR) 
{ 
    printf("Failed. Error Code : %d",WSAGetLastError()); 
    return 1; 
} 
printf("Initialised.\n");  

if((listenSocket = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP)) == INVALID_SOCKET) //IPv4, TCP 
{ 
    printf("Could not create socket : %d" , WSAGetLastError()); 
    WSACleanup(); 
    return 1; 
} 

printf("Socket created.\n"); 

memset(&server, '0', sizeof(server)); 
memset(sendbuf, '0', sizeof(sendbuf)); 

server.sin_family = AF_INET; 
//server.sin_addr.s_addr = htonl(0x7F000001); //localhost - 127.0.0.1 
server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
//server.sin_addr.s_addr = inet_addr("10.48.53.166"); 
server.sin_port = htons(7368); 

if(bind(listenSocket ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) 
{ 
    printf("Bind failed with error code : %d" , WSAGetLastError()); 
    closesocket(listenSocket); 
    WSACleanup(); 
    return 1; 
} 

puts("Bind done"); 

listen(listenSocket, 10); 

//Accept and incoming connection 
puts("Waiting for incoming connections..."); 


c = sizeof(struct sockaddr_in); 

message = "{\"id\":2,\"result\":{\"code\":\"999\",\"message\":\"AddPageRange StartIndex don't match Inspection Counter\"},\"Client_ID\":\"PQCS1\",\"jsonrpc\":\"2.0\",\"Protocol\":\"2H\"}"; 

while((clientSocket = accept(listenSocket , (struct sockaddr *)NULL, NULL)) != INVALID_SOCKET) 
{ 
    puts("Connection accepted");   
    do { 
     iResult = recv(clientSocket, recvbuf, recvbuflen, 0); 
     if (iResult > 0) 
     { 
      printf("Bytes received: %d\n", iResult); 
      recvbuf[iResult] = '\0'; 
      outputCounter = 0; 
      while(recvbuf[outputCounter] != '\0') 
       printf("%X", (unsigned char)recvbuf[outputCounter++]);    
      iSendResult = send(clientSocket, message, strlen(message), 0); 
      if (iSendResult == SOCKET_ERROR) 
      { 
       printf("send failed with error: %d\n", WSAGetLastError()); 
       closesocket(clientSocket); 
       WSACleanup(); 
       return 1; 
      } 
      printf("Bytes sent: %d\n", iSendResult); 
     } 
     else if (iResult == 0) 
      printf("Connection closed\n"); 
     else 
      printf("recv failed: %d\n", WSAGetLastError()); 
    } while(iResult > 0); 

} 
if (clientSocket == INVALID_SOCKET) 
{ 
    printf("accept failed with error code : %d" , WSAGetLastError()); 
    return 1; 
} 
closesocket(listenSocket); 
WSACleanup(); 

return 0; 
} 
+2

Было бы лучше использовать 'unsigned char' вместо' char' для 'sendbuf []' и 'recvbuf []'. –

ответ

1

Ваш recvbuf имеет тип полукокса, который является подозреваемым подписан на вашей платформе. Оба байта вашего сообщения составляют> 127 (десятичный) и поэтому считаются отрицательными. Спецификатор формата printf ("% X") ожидает целое число (32 бит на вашей платформе по внешнему виду), поэтому число расширяет знак (заполняет наиболее значимые 24 бита целого с самым значительным битом байта) ,

Попробуйте распечатать, сколько байтов вы получили. Также измените ваш printf на

printf("%X", ((int)recvbuf[outputCounter++]) & 0xff);    
+1

Немного сложно просто преобразовать знаковое значение в непознанный. Более простым решением может быть 'printf («% X », (unsigned char) recvbuf [outputCounter ++]);' или объявить 'unsigned char recvbuf [DEFAULT_BUFLEN];'. –

+0

Я попытался изменить тип recvbuf на unsigned char, но дело в том, что метод recv() не принимает unsigned char для этого параметра. Я получаю ошибку компиляции: «невозможно преобразовать параметр 2 из unsigned char [512] в char *» – user2963830

+0

@ user2963830 Второй параметр [recv] (http://man7.org/linux/man-pages/man2/recv. 2.html) является «void *». Он принимает все указатели. Так что, наверное, вы что-то написали плохо. Добавьте измененный код в сообщение. – LPs

0

У вас возникли проблемы с printf.

Глядя на The Man

o, u, x, X

The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation. The letters abcdef are used for x conversions; the letters ABCDEF are used for X conversions. The precision, if any, gives the minimum number of digits that must appear; if the converted value requires fewer digits, it is padded on the left with zeros. The default precision is 1. When 0 is printed with an explicit precision 0, the output is empty.

курсив мой

Таким образом, используя %X в качестве спецификатора формата, ваши данные способствовали бы unsigned int и вы должны передать его выбора только байт вы хотите быть напечатан:

printf("Byte %d: %X\n", outputCounter, recvbuf[outputCounter++] & 0xFF);