Добавление данных к нулевому символу в массиве символов для отправки данных через сокет - PullRequest
2 голосов
/ 15 сентября 2009

Я начинающий программист. У меня проблема, как показано ниже,

void SockSend()  
{  
char *sendbuf;  
int sendsize;   /* send data size(variable size)*/  
int iPos = 0, iTotSize;  
char hdr;  
char *data = "ABCDEFGHIJKLMNO";   /* its just example, data can be any thing */  
sendsize = strlen(data);  

hdr = '\0';   /* header character */  
sendbuf = (char*)malloc(sendsize + 2);  
sendbuf[iPos] = hdr;  
iPos++;  
strncpy(sendbuf + iPos, data, 15);  
iPos += sendsize;  
sendbuf[iPos] = '\0';   /* append null at end of string*/  

iTotSize = strlen(sendbuf);  

send(sockid, sendbuf, iTotSize, 0);  
}

Как и в приведенном выше коде, мне нужно отправить данные с присоединенным символом заголовка. если символ заголовка ascii находится между 1h - ffh, отличный от 0h, работает правильно. Я знаю, что если в строку добавляется ноль, он считается концом строки. Но мне нужно отправить NULL символ с данными через сокет. Может кто-нибудь, пожалуйста, помогите мне, как решить эту проблему.

Заранее спасибо

Ответы [ 5 ]

4 голосов
/ 15 сентября 2009

Если вы хотите избежать нулевого завершения, вы должны прекратить обрабатывать ваши данные как строку. strcpy предназначен для копирования только строк с нулевым символом в конце. Он реализован для копирования каждого байта, пока не встретит # 0. memcpy может скопировать любую ячейку памяти. Он не связан строкой с нулевым символом в конце. Поскольку memcpy не может определить размер копируемых данных, вы должны предоставить эту информацию. Кроме того, вы не должны использовать strlen, так как он связан теми же правилами завершения.

1 голос
/ 15 сентября 2009

Если вам приходится иметь дело с данными, содержащими '\0', сохраняйте их размеры отдельно и используйте memcpy вместо strcpy или strncpy.

Обратите внимание, что в вашем примере вы уже вычислили правильную длину пакета данных при выделении памяти для sendbuf. Просто используйте это значение (-1). Также обратите внимание, что вы обеспечили достаточно места для данных в send buf, поэтому вы можете безопасно использовать strcpy. strncpy не завершает строку вывода при достижении предела - подвержен ошибкам.

При работе с размером в C используйте size_t тип, определенный в stdlib.h вместо int.

Надеюсь, это поможет ...

void SockSend()  
{  
    char *sendbuf;  
    int sendsize;   /* send data size(variable size)*/  
    int iPos = 0, iTotSize;  
    char hdr;  
    char *data = "ABCDEFGHIJKLMNO"; 
    sendsize = strlen(data);  /* -- Are you sure that data will not contain \0 ? */

    hdr = '\0';   /* header character */
    sendbuf = (char*)malloc(sendsize + 2);  /* -- Data size calculation! */
    sendbuf[iPos] = hdr;  
    iPos++;  
    strcpy(sendbuf + iPos, data);  
    iPos += sendsize;  
    sendbuf[iPos] = '\0';   /* append null at end of string*/  

    iTotSize = strlen(sendbuf);  

    send(sockid, sendbuf, iTotSize, 0);  
}
1 голос
/ 15 сентября 2009
iTotSize = strlen(sendbuf);

strlen(sendbuf) прекратит считать символы, как только найдет нулевой символ.

Подсчитайте общий размер, добавив различные размеры вручную .

Может быть, это может помочь: iTotSize = 1 + strlen(sendbuf + 1);

0 голосов
/ 15 сентября 2009

Поскольку никто еще не указал на это - у вас утечка памяти здесь. Вам нужно вызвать free(sendbuf); где-нибудь после того, как вы отправили байты и прежде чем вернуться из функции.

Существует также вероятность того, что sent() вернет короткий счет - когда стек TCP принимает меньше данных, чем вы его предоставили, т. Е. Буфер отправки сокета заполнен - ​​поэтому вы должны проверить возвращаемое значение. 1009 *

0 голосов
/ 15 сентября 2009

strlen останавливается на символе NUL и не считает его. Вы можете просто добавить один к этой длине

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...