2015-05-06 5 views
0

Я пытаюсь читать символы из сокета; вот функция, которую я создал для этого, во многом вдохновленный Here, где я удаляю некоторые нерелевантные части здесь (этот образец компилируется правильно).Проблема при чтении из сокета

int process(int socketfd, void *buffer, int n) 
{ 
    int totread = 0; 
    char ch; 
    int numread; 

    for(;;) 
    { 
    numread = read(socketfd, &ch, 1); 

    if(numread == 0) { 
     if (totread == 0) { 
      return 0; 
     } else { 
      break; 
     } 
    } else { 
     if(totread < n-1) { 
      totread++; 
      printf("totread: %d\n", totread); 
      printf("Here is OK, ch value gets printed %c\n", ch); 
      *buffer++ = ch; 
      printf("With help provided, this line gets printed\n"); 
      printf("But the value <%s> of buffer, is blank (<> output)\n, buffer); 
     } 
     if (ch == '\n') { 
      printf("%c\n", ch); 
      printf("%s\n", buffer); 
      break; 
     } 
    } 
} 
return totread; 
} 

Я не могу понять, почему вторая строка не печатается. Очевидно, что инструкция *buf++ = ch не работает; Но это выглядит правильно. Это просто влияет на символ, читаемый на следующее значение массива символов buf. Во время компиляции я не вижу ошибок или предупреждений, клиент отключается после того, как первая строка будет напечатана, а вторая не будет достигнута.

EDIT

Вот как я инициализировать мой буфер:

char *buffer = ""; 
int l = process(newsockfd, buffer, 100); 
printf("Number read (function network) %d\n", l); 

Это, вероятно, не является подходящим способом сделать это; Я также попытался указать фиксированную длину, такую ​​как char buffer = [255];. Функция не выходит, но ничего не печатается. Я довольно новичок в программировании на С, большое спасибо за вашу помощь!

+0

Когда вы говорите, что вторая строка не печатается, я полагаю, вы имеете в виду, потому что программа вылетает. Вероятно, это будет segv, вызванный написанием 'buf', когда' buf' является либо 'NULL', либо недопустимой памятью. Что происходит, когда вы запускаете его под 'gdb', скомпилировав с помощью' -g' для включения отладочных символов? – abligh

+1

Буфер достаточно большой? Кроме того, я считаю, что buf [0] никогда не записывается, кажется, что потенциальная проблема может случиться. – cen

+0

Пожалуйста, также покажите нам, как ** вы вызываете эту функцию и, в частности, как передается буфер, и ** инициализируется **. – alk

ответ

2
int process(..., void * b, ... 
{ 
    ... 

    *b++ = ... 

Разыменование и/или инкрементируя void -указатель не действует C. Компилятор должен иметь по крайней мере предупреждал вас об этом.

Перекомпилируйте код со всеми предупреждениями (для gcc передать опции -Wall -Wextra -pedantic для этого). Затем исправьте код, пока не будет выдано больше предупреждений.


Ссылаясь правку о том, как рассматриваемая функция называется:

Это

char *buffer = ""; 

не объявляет буфер, но только указатель. Этот указатель указывает на строковый литерал размером 1. Строковые литералы постоянны по определению.

Подводя итог: Вы предоставляете вашему process() -функцию указатель на постоянную память размером 1.

Проблемы, связанные с этим:

  1. Вы cannnot чтения в постоянную память.
  2. Даже если 1. не применяется, вы можете читать только в 1 байт.

Чтобы исправить это изменение кода следующим образом:

char buffer[100] = ""; /* Define a buffer of 100 characters size and 
          initialise it to all `0`s. */ 
int l = process(newsockfd, buffer, 100); 

Согласно process() блокирования, вы должны смотреть на функции read(): Если она вызывается, но отправитель не посылает ничего он просто не возвращается, пока соединение все еще продолжается.

И: Сделать process() обрабатывать значение, переданное как n.

+0

Я использую eclipse как IDE; возможно, это не лучший выбор для программирования на C:/ – philippe

+1

@philippe: Eclipse отлично работает для программирования на C, по крайней мере, если вы правильно .. ;-) Если вы используете CDT, вы используете gcc в любом случае. Eclipse - это не компилятор/компоновщик, а только среда IDE. – alk

+0

@philippe: См. Мой обновленный ответ. – alk

0

Попробуйте изменить первую строку на char * buf = (char *) buffer; и скомпилировать с использованием gcc с -Werror на

+0

Это не случайно: / – philippe

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