簡體   English   中英

在同一個 UDP 數據包中發送 ASCII 字符和 int

[英]Sending ASCII characters and int in the same UDP packet

我需要通過int套接字發送一個數據包,其中將有一個六位數字,寫為 ASCII 字符串,在換行符之后,相同的數字,但以字節為單位,如下所示: 31 32 33 34 35 36 0A 00 01 E2 40對應於123456\n(123456) - integer 在括號中。 到目前為止,我可以發送我的字符串和我的換行符,但是當涉及到一個int時,我得到 0 個字節被寫入緩沖區,而我的int緩沖區數組中沒有任何內容被發送。 此外,如果我檢查int緩沖區數組的文本內容,它的“Fs”數量很奇怪: 00 01 FFFFFFE2 40

這是我的 UDP 客戶端:

#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>


char buf[11];

int main(int argc, char **argv)
{
    struct sockaddr_in adr;
    int sock, r;
    unsigned int port;
    char abcd[512];
    char intBuff[4];
    unsigned int index = 123456;
    unsigned int networkHost;
    networkHost = htonl(index);

    memcpy(intBuff, (char*)&networkHost,sizeof(uint32_t));
    printf("Int buffer: ");
      for(int i=0; i<sizeof(uint32_t); i++){
        printf("%02X ", intBuff[i]); //Output is 00 01 FFFFFFE2 40
    }

    int x1 = sprintf(buf,"%s\n","123456"); 
    printf("\n1st data write: %i\n", x1); //7 bytes are written


    int x2 = sprintf(&buf[x1], "%s",intBuff); 
    printf("2nd data write: %i\n", x2); //0 bytes are written


    //SERVER
    printf("IP: ");
    scanf("%s", abcd);
    printf("PORT: ");
    scanf("%u", &port);

    sock = socket(AF_INET, SOCK_DGRAM, 0);
    adr.sin_family = AF_INET;
    adr.sin_port = htons(port);
    adr.sin_addr.s_addr = inet_addr(abcd);


    r = sendto(sock,
               buf,
               11,
               0,
               (struct sockaddr*) &adr,
               sizeof(adr));

    close(sock);
    return 0;
}

問題

出現奇怪的值是因為您的char數組是有signed的,當您將它傳遞給 printf 時,編譯器會將其解釋為有signedprintf

不要使用sprintf(...,"%s", ...)復制可能包含零字節的二進制數據,因為"%s"格式在到達\0 null 字符時會突然停止復制。


解決方案

  1. 使用unsigned char ,因此編譯器在將數據傳遞給 printf 時不會將其解釋為帶signedprintf
  2. 使用memcpyintBuff復制到buf

代碼示例


#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <arpa/inet.h>

int main() {
    unsigned char buf[11];
    unsigned char intBuff[sizeof(uint32_t)];
    uint32_t index = 123456;
    uint32_t networkHost;
    networkHost = htonl(index);

    memcpy(intBuff, &networkHost, sizeof(networkHost));

    for (int i=0; i < sizeof(intBuff); i++){
      printf("%02x ", intBuff[i]);
    }

    int x1 = sprintf(buf,"%s\n","123456"); 
    printf("\n1st data write: %i\n", x1); // 7 bytes are written


    // It is certain that the write is sizeof(intBuff) in size.
    memcpy(&buf[x1], intBuff, sizeof(intBuff));

    int total_len = x1 + sizeof(intBuff);

    printf("Packed data: ");
    for (int i = 0; i < total_len; i++) {
      printf("%02x ", buf[i]);
    }

    putchar('\n');
}

Output

ammarfaizi2@integral:/tmp$ gcc x.c -o x 
ammarfaizi2@integral:/tmp$ ./x
00 01 e2 40 
1st data write: 7
Packed data: 31 32 33 34 35 36 0a 00 01 e2 40 
ammarfaizi2@integral:/tmp$ 

代表 integer 的字節通常可以具有任何值,因為 integer 具有各種值。 所以一個字節可能為零。 然后使用printf%s將這些字節寫入緩沖區將在零字節處停止,因為%s需要一個字符串。 字符串的定義是它是一個字符序列,其結尾用零字節標記。

使用您使用的值,第一個字節為零,因此printf立即停止,並且不寫入任何字節。

不要使用printf將字節復制到緩沖區中,而是直接使用memcpy復制它們:

memcpy(&buf[x1], &networkHost, sizeof networkHost);

您根本不需要intBuff並且可以將其從程序中刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM