Abh*_*hek 1 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;
}
Run Code Online (Sandbox Code Playgroud)
基本上getMessage函数(fd)的输入是我在main方法中声明的侦听套接字的输入.我已经验证输出是正确的.现在我需要将文件描述符的输出转换为字符串并返回该字符串.但每次我运行我的服务器时都会陷入while循环.不执行循环中的语句.编辑:添加循环终止条件:现在它跳转到"块长度"immediatley.非常感谢帮助!
如果您正在使用POSIX 2008 getline()函数,那么您将丢弃有用的信息(它返回它读取的行的长度,因此如果您捕获该信息,则不需要strlen()循环.
如果代码在getline()调用时阻塞,则可能意味着上游套接字未关闭,但不再发送数据.您的发送代码需要关闭套接字,以便此代码可以检测EOF.
或者,既然你讨论'空白行',那么你的代码可能应该检查一行只包含\r\n(或者只是\n)并打破循环; 你的代码目前没有这样做.
您的循环也表现出二次行为,因为您反复使用strcat().你最好密切关注字符串的结尾和strcpy()旧的数据之后的新数据,然后将指针调整到字符串的结尾.
在进一步审查时,我注意到您使用fdopen()基于文件描述符打开文件流,但您既不关闭它也不将文件流返回给调用者以进行关闭.这导致泄漏问题.
经验法则:如果您分配资源,则应将其释放,或将其传回以释放.
我建议更改界面以使用已打开的FILE *,并fdopen()在调用代码中执行.或者,如果您不再需要文件描述符,则可以fclose()在返回之前保留当前接口并使用,但这也将关闭基础文件描述符.
此代码适用于我(MacOS X 10.7.2; XCode 4.2.1):
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char *getMessage(FILE *);
char *getMessage(FILE *fp)
{
char *block = 0;
size_t size = 0;
size_t buffersize = 0;
char *buffer = 0;
ssize_t newlen;
while ((newlen = getline(&buffer, &buffersize, fp)) > 0)
{
printf("Buffer length: %ld\n", (long)newlen);
block = realloc(block, size + newlen + 1);
strcat(&block[size], buffer);
size += newlen;
if (strcmp(buffer, "\r\n") == 0)
break;
}
printf("Block length: %zd\n", size);
if (size > 0)
printf("<<%s>>\n", block);
return block;
}
int main(void)
{
char *msg;
while ((msg = getMessage(stdin)) != 0)
{
printf("Double check: <<%s>>\n", msg);
free(msg);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用一个带有DOS样式行结尾的文件作为标准输入进行了测试,最后一行是空白行,非空行.连续两个空行也似乎没问题.
char buffer = (char *) malloc (buffersize + 1);
Run Code Online (Sandbox Code Playgroud)
应该:
char *buffer = malloc (buffersize + 1);
Run Code Online (Sandbox Code Playgroud)