2016-09-02 3 views
0

У меня возникла проблема, я действительно не мог решить, поэтому я перезапустил. У меня была проблема с инкапсуляцией данных или более конкретными без инкапсуляции. Поэтому после того, как я понял, эта инкапсуляция полезна, я начал переписывать код.Два раза отправить и recv не работают C

Теперь я столкнулся с другой проблемой. Как-то мои призывы отправки и возврата не работают так, как я хочу, чтобы они были.

Вот та часть, где я отправляю:

char to_send[] = "hello. I am the Data."; 

    // get size of data 
    int len = strlen(to_send); 
    char slen[len]; 
    sprintf(slen,"%d",len); 
    printf("%s\n",slen); 
    // send size of data 
    if(send(comm_fd,slen,len,0)<0){perror("Error on send"); exit(1);} 

    // send data 
    if(send(comm_fd,to_send,len,0)<0){perror("Error on send"); exit(1);} 

А вот часть, где я ПРИЕМ:

// getting size of bytes to recv 
    char buf[1000]; 
    bzero(buf,1000); 

    int rec = recv(comm_fd, buf, 100,0); 
    printf("rec\n: %i",rec); 
    printf("buf\n: %s\n", buf); 

    int buffsize; 
    buffsize = atoi(buf); 
    bzero(buf,1000); 
    printf("buffsize: %i\n",buffsize); 

    // recv the bytes 
    bzero(buf,1000); 
    rec = recv(comm_fd, buf, buffsize,0); 
    printf("rec\n: %i",rec); 
    printf("%s",buf); 

Так что моя проблема сейчас: я могу ПРИЕМ размера следующих данных и печатей Это. Но сами данные не отображаются.

Может кто-нибудь мне помочь? Я думаю, что я делаю основные вещи неправильно (я новичок в C и сетевого программирования)

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

+2

'slen' размер не' len' – Fozi

ответ

3

Две вещи с этой первой send вызова:

if(send(comm_fd,slen,len,0)<0){perror("Error on send"); exit(1);} 

Здесь вы отправляете len Число байтов, но len - это длина to_send, а не длина slen. Вы, скорее всего, передавать данные из-за пределов инициализированными частей slen, что приводит к непредсказуемому поведению

Вторая проблема заключается в том, что вы отправляете длину to_send в виде строки переменной длины, так что получил на самом деле не знаю, сколько получить. В вашем случае вы могли бы (и, вероятно, сделать) получить длину и строку в одном вызове recv. По крайней мере, если вы используете TCP (streaming).

Обе эти проблемы можно решить, сделав slen массив фиксированного размера, достаточно большой, чтобы удерживать наибольшие числа, о которых вы можете думать (обычно десять цифр), а затем отправить этот массив фиксированной длины, используя sizeof slen.

Возможно, что-то вроде этого:

// Ten digits, plus string terminator 
char slen[10 + 1]; 

// Prefix length with zeroes, and don't overflow the buffer 
snprintf(slen, sizeof(slen), "%010d", strlen(to_send)); 

// Send the whole array, including terminator 
send(comm_fd, slen, sizeof slen, 0); 

Затем на приемной стороне, вы могли бы сделать

// Ten digits, plus string terminator 
char slen[10 + 1]; 

// Receive the whole string, including terminator 
recv(comm_fd, slen, sizeof(slen), 0); 

// Convert to a number 
size_t len = strtoul(slen, NULL, 10); 

// Now receive `len` bytes 

Обратите внимание, что у меня нет проверки ошибок, которые вы должны иметь.

+0

он сработал! большое спасибо! Я вижу, что мои ошибки будут читать о функциях, которые вы использовали. спасибо – Minory

+1

Кроме того, в современных программах используйте 'memset' вместо' bzero' (который устарел POSIX) –

+1

'snprintf (slen, sizeof (slen),"% 010d ", strlen (to_send));' имеет проблемы. Типичный 'int' (который является типом, ожидаемым с'% d'), требует до 11 + 1 'char', а не 10. например. '-2147483648'. 'strlen()' возвращает тип 'size_t', который может не соответствовать'% d'. Возможно, вам нужно '% zu', тогда 10 может быть в порядке.Код, который использует 'snprintf()' для предотвращения перерасхода и не проверяет возвращаемое значение 'snprintf()', торгует одной проблемой для другой. Лучше проверить его возвращаемое значение. – chux

 Смежные вопросы

  • Нет связанных вопросов^_^