2016-11-03 2 views
1

될 나는 다음과 같은 문제가 있습니다C-서버 소켓이 잘못 패킷

  • 내가 문자열을 보낼 아파치 미나 프레임 워크를 사용하여 자바 클라이언트가 있습니다.
  • 문자열을 수신 할 C 서버를 작성했습니다.
  • 그래서, 서버에 UTF8 문자를 보내려고 : myStringToSend = "A"
  • 내가 아니라 문자열을 변환 바이트 또는 16 진수와 미나의 패킷을 볼 수있는 미나 소스를 디버깅, 그것은 0xC30x84을 보내도록 .
  • 또한 wireshark 네트워크 뷰어에서 보낸 패킷을 확인하고 패킷으로 모두 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

'char' 대신'unsigned char'을 사용하는 것이 좋습니다. 'sendbuf []'와'recvbuf []'둘 다. –

답변

1

귀하의 recvbuf은 용의자가 플랫폼에 서명입니다 char 형이다. 메시지의 두 바이트 모두> 127 (십진수)이므로 음수로 간주됩니다. printf ("% X") 형식 지정자는 숫자가 부호 확장을 갖도록 (정수의 최상위 24 비트를 바이트의 최상위 비트로 채 웁니다) 정수 (해당 플랫폼에서 32 비트)를 기대합니다. .

수신 한 바이트 수를 인쇄 해보십시오. 또한 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를 부호없는 char [512]에서 char *로 변환 할 수 없습니다." – user2963830

+0

@ user2963830 [recv]의 두 번째 매개 변수 (http://man7.org/linux/manage/man2/recv. 2.html)은'void * '입니다. 그것은 모든 포인터를 받아들입니다. 그래서 아마도 당신은 뭔가 나쁜 것을 썼습니다. 수정 된 코드를 게시물에 추가하십시오. – LPs

0

으로 변경하십시오. printf에 문제가 있습니다.

, 데이터가 촉진되는 형식 지정자로 %X를 사용하여,

그래서 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.

강조 광산에서 unsigned int 않는 찾고 그리고 당신은 당신이 원하는 경우에만 바이트를 선택 통과해야 인쇄 :

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