C getline函数不按指定读取行

时间:2011-11-26 18:00:30

标签: c webserver httprequest getline

我需要getline()来读取我的浏览器发送到我正在编程的网络服务器的请求标头。这是应该执行该任务的getMessage函数:

char *getMessage(int fd) {
  FILE *sstream = fdopen(fd, "r");
  // initialise block to 1 char and set it to null
  char *block = malloc(sizeof(char));
  *block = '\0';
  int size = 1;

  // Read from the file descriptor fd (using a FILE stream) until a blank line is
  // received.
  // Read 100 lines (buffersize) from sstream and put into the buffer. If lines have
  // been successfully read concatenate them with block.
  int buffersize = 100;
  char *buffer = malloc (buffersize + 1);

  while(getline(&buffer,&buffersize,sstream) != -1){
     int length = strlen(buffer);
     printf("Buffer length: %d\n",length);
     block = realloc(block,strlen(block)+strlen(buffer)+1);
     strcat(block,buffer);
     if(strcmp(buffer,"\r\n") == 0) break;
 }

  int len = strlen(block);
  printf("Block length: %d\n", len);
  printf("%s \n", block);
  return block;
} 

基本上getMessage函数(fd)的输入是我在main方法中声明的侦听套接字的输入。我已经验证输出是正确的。现在我需要将文件描述符的输出转换为字符串并返回该字符串。但每次我运行我的服务器时都会陷入while循环。不执行循环中的语句。 编辑:添加循环终止条件:现在它跳转到“块长度”immediatley。 非常感谢帮助!

2 个答案:

答案 0 :(得分:5)

如果您正在使用POSIX 2008 getline()函数,那么您将丢弃有用信息(它返回它读取的行的长度,因此如果您捕获该信息,则不需要{{ 1}}在循环中。

如果代码在strlen()调用时阻塞,则可能意味着上游套接字未关闭,但不再发送任何数据。您的发送代码需要关闭套接字,以便此代码可以检测到EOF。

或者,既然你讨论'空白行',那么你的代码可能应该检查一行只包含getline()(或者只是\r\n)并打破循环;你的代码目前没有这样做。

您的循环也表现出二次行为,因为您反复使用\n。您最好密切关注字符串的结尾,并简单地strcat()旧数据之后的新数据,然后将指针调整到字符串的结尾。


在进一步审核时,我注意到您使用strcpy()根据文件描述符打开文件流,但您既不关闭它也不将文件流返回给调用者以进行关闭。这会导致泄漏问题。

经验法则:如果您分配资源,则应将其释放,或将其传回以释放。

我建议更改界面以使用已打开的fdopen(),并在调用代码中执行FILE *。或者,如果您不再需要文件描述符,则可以保留当前接口并在返回之前使用fdopen(),但这也将关闭基础文件描述符。

此代码适用于我(MacOS X 10.7.2; XCode 4.2.1):

fclose()

我用一个带有DOS样式行结尾的文件作为标准输入进行测试,最后一行是空白行,非空行。连续两个空行也似乎没问题。

答案 1 :(得分:5)

char buffer = (char *) malloc (buffersize + 1);

应该是:

char *buffer = malloc (buffersize + 1);