2016-11-03 33 views
1

我有以下问题:C-服务器套接字成为错误的数据包

  • 我使用Apache米娜框架发送字符串Java的客户端。
  • 我写了一个C服务器来接收字符串。
  • 所以,我想一个UTF8字符发送到服务器:myStringToSend =“A”
  • 我调试的米娜源看到字节或十六进制和米娜的数据包转换成字符串很好,所以它发送0xC30x84
  • 我也检查wireshark网络查看器中发送的数据包,它也看到0xC30x84作为数据包,一切ok。
  • 但我的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是char类型是犯罪嫌疑人是你的平台上签署的。消息的两个字节都是> 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()不接受此参数的无符号字符。我得到一个编译错误:“无法将参数2从无符号字符[512]转换为字符*” – 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);