简体   繁体   English

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

[英]receive and send data throught socket in C

I want to receive a string, make a reverse and resend it through a socket. 我想接收一个字符串,进行反转并通过套接字重新发送。 The string is encoded with 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);

I receive the number and the string correctly but when I make the conversion I get some extra caracters like in this output 我正确地收到了数字和字符串,但是当我进行转换时,我在输出中得到了一些额外的字符

<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>

OK, putting together all the information you have in different questions (eg receive and reverse a string asn.1 ) I've reproduced your problem. 好的,将您在不同问题中拥有的所有信息汇总在一起(例如, 接收并反转字符串asn.1 ),我重现了您的问题。

First the solution to the problem: You are not null terminating the reverseString. 首先,解决该问题:终止reverseString不能为null。 That's why when you try to print there's garbage after it. 这就是为什么当您尝试打印时会出现垃圾的原因。 Solution is simply to add after the for loop 解决方案是在for循环之后添加

reverseString[i]='\0';

... I'm not 100% sure that the received string is null terminated (it might, they are probably nice and do it for you)... but even if that's the case, the size field does not include the end-of-string '\\0' ...我不是100%确定接收到的字符串以null终止(这可能很不错,可以为您做这件事)...但是,即使是这种情况,大小字段也不包括结尾-字符串'\\ 0'

Now, a bit of background. 现在,有一些背景知识。 Your definition (according to the question cited above) is: 您的定义(根据上述问题)是:

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

In ASN.1 strings there's no need for a null-termination convention for strings, since length of values is always well defined in the Tag-Length-Value structure. 在ASN.1字符串中,不需要为字符串设置空终止约定,因为值的长度始终在Tag-Length-Value结构中定义良好。 In fact, the online compiler you are using handles PrintableString as OCTET STRING, which can give you a hint that everything is being treated as a raw buffer. 实际上,您使用的在线编译器将PrintableString处理为OCTET STRING,这可以向您暗示所有内容都被视为原始缓冲区。

So, for example if you sent number=100 and string="Hello World" you will get in the DER encoding: 因此,例如,如果您发送了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"

I haven't used this compiler for any serious stuff (I've only used to try to reproduce the problem), si I cannot say what is the recommended best practice for OCTETSTRINGS or PrintableStrings, but be wary of char buffer.... 我没有用过任何严重的东西(我只是用来重现该问题)的编译器,我不能说推荐的OCTETSTRINGS或PrintableStrings最佳实践是什么,但是要警惕char缓冲区。

Finally, my complete program (instead of sending it through a socket, I'm encoding to a buffer and decoding from the same buffer) 最后,是我完整的程序(不是通过套接字发送,而是编码到缓冲区并从同一缓冲区解码)

#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);

}

The following line is likely faulty: 以下行可能是错误的:

int byte_count = message2->string.size;

The string.size likely isn't what you expect. string.size可能不是您期望的。 This is probably the storage size of the buffer, and not the length of the string inside the buffer. 这可能是缓冲区的存储大小,而不是缓冲区内部字符串的长度。

This is why you see ffffffda etc. (they are negative numbers, you're subtracting from 0, most likely). 这就是为什么您看到ffffffda等的原因(它们是负数,很可能是从0中减去)。

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

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