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

时间:2014-05-12 11:20:33

标签: c string sockets asn.1

我想收到一个字符串,反转并通过套接字重新发送。该字符串使用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>

2 个答案:

答案 0 :(得分:1)

好的,将您在不同问题中的所有信息汇总在一起(例如receive and reverse a string asn.1)我已经复制了您的问题。

首先解决问题的方法:你不是null终止reverseString。这就是为什么当你试图在它之后打印那里的垃圾时。解决方案只是在for循环后添加

reverseString[i]='\0';

...我不能100%确定收到的字符串是否为空终止(可能,它们可能很好并为你做)...但即使这样, size字段不包括字符串结尾&#39; \ 0&#39;

现在,有点背景知识。您的定义(根据上面提到的问题)是:

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

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

所以,例如,如果你发送了number = 100和string =&#34; Hello World&#34;你会得到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);

}

答案 1 :(得分:0)

以下行可能有问题:

int byte_count = message2->string.size;

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

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

相关问题