繁体   English   中英

通过C中的套接字接收和发送数据

[英]receive and send data throught socket in C

我想接收一个字符串,进行反转并通过套接字重新发送。 该字符串使用ASN.1编码。

recv( to_server_socket, &buffer2, sizeof( buffer2 ), MSG_WAITALL );
ber_decode(0, &asn_DEF_Message02, (void**) &message2, buffer2, sizeof buffer2);
xer_fprint(stdout, &asn_DEF_Message02, message2);
printf( "Server --> %d\n", message2->number );  
char* serverString = message2->string.buf;
    int byte_count = message2->string.size;
    char reverseString[50];
    int i=0;
    for(i=0; i < byte_count; ++i)
    {
      char c = serverString[i];
      if(c=='\0')
      {
        reverseString[i] = '\0';
        break;
      }
      else if(c>=65 && c<=90)
        reverseString[i] = c+32;
      else if(c>=97 && c<=122)
        reverseString[i] = c-32;
      else
        reverseString[i] = c;
    }
    printf("String to send: %s\n", reverseString);

我正确地收到了数字和字符串,但是当我进行转换时,我在输出中得到了一些额外的字符

<Message02>
    <number>35</number>
    <string>Dh3i5KhQNM5OgNh6O</string>
</Message02>
Server --> 35
String to send: dH3I5kHqnm5oGnH6oڹQ
msg3_buf: 
30 16 13 14 64 48 33 49 35 6b 48 71 6e 6d 35 6f 47 6e 48 36 6f ffffffda ffffffb9 51 00 00 <Message03>
    <string>dH3I5kHqnm5oGnH6oڹQ</string>
</Message03>

好的,将您在不同问题中拥有的所有信息汇总在一起(例如, 接收并反转字符串asn.1 ),我重现了您的问题。

首先,解决该问题:终止reverseString不能为null。 这就是为什么当您尝试打印时会出现垃圾的原因。 解决方案是在for循环之后添加

reverseString[i]='\0';

...我不是100%确定接收到的字符串以null终止(这可能很不错,可以为您做这件事)...但是,即使是这种情况,大小字段也不包括结尾-字符串'\\ 0'

现在,有一些背景知识。 您的定义(根据上述问题)是:

Message02 ::= SEQUENCE {
    number INTEGER, -- incremented integer
    string PrintableString (SIZE (10..20)) -- random string
}

在ASN.1字符串中,不需要为字符串设置空终止约定,因为值的长度始终在Tag-Length-Value结构中定义良好。 实际上,您使用的在线编译器将PrintableString处理为OCTET STRING,这可以向您暗示所有内容都被视为原始缓冲区。

因此,例如,如果您发送了number = 100和string =“ Hello World”,您将获得DER编码:

30 10 // 0x30 = SEQUENCE, 0x10 = Length 16
   02 01 64  // 0x02 = INTEGER, 0x01 = Lenght 1, 0x64= Value 100
   13 0b 48 65 6c 6c 6f 20 57 6f 72 6c 64 // 0x13 = PrintableString 0x0b= Length 11, value= "Hello World"

我没有用过任何严重的东西(我只是用来重现该问题)的编译器,我不能说推荐的OCTETSTRINGS或PrintableStrings最佳实践是什么,但是要警惕char缓冲区。

最后,是我完整的程序(不是通过套接字发送,而是编码到缓冲区并从同一缓冲区解码)

#include "Message02.h"
#include <string.h>


#define BUFFERSIZE 100

int main() {
    Message02_t *message1;
    char buffer2[BUFFERSIZE];
    int ival=100;
    char *sval="Hello World";

    message1 = calloc(1, sizeof(Message02_t));
    message1->number = 100;
    message1->string.buf = sval;
    message1->string.size = strlen(sval);
    der_encode_to_buffer(&asn_DEF_Message02, message1, buffer2, BUFFERSIZE);

    //receive Message02
    Message02_t *message2 = 0;
    message2 = calloc(1, sizeof(Message02_t));
    //recv( to_server_socket, &buffer2, sizeof( buffer2 ), MSG_WAITALL );
    ber_decode(0, &asn_DEF_Message02, (void**) &message2, buffer2, sizeof buffer2);
    xer_fprint(stdout, &asn_DEF_Message02, message2);
    printf( "received number %d\n", message2->number );
    printf( "received String %s\n", message2->string.buf );
    printf( "received String size %d\n", message2->string.size );

    int j;
    for(j=0;j<BUFFERSIZE;j++) {
       printf("%02x",buffer2[j]);
    }
    printf("\n");

    char* serverString = message2->string.buf;
    int byte_count = message2->string.size;
    char reverseString[50];
    int i=0;
    for(i=0; i < byte_count; ++i)
    {
      char c = serverString[i];
      if(c=='\0')
      {
        reverseString[i] = '\0';
        break;
      }
      else if(c>=65 && c<=90)
        reverseString[i] = c+32;
      else if(c>=97 && c<=122)
        reverseString[i] = c-32;
      else
        reverseString[i] = c;
    }
    reverseString[i]='\0'; /* <=== THIS IS THE FIX */
    printf("String to send: %s\n", reverseString);

}

以下行可能是错误的:

int byte_count = message2->string.size;

string.size可能不是您期望的。 这可能是缓冲区的存储大小,而不是缓冲区内部字符串的长度。

这就是为什么您看到ffffffda等的原因(它们是负数,很可能是从0中减去)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM