我正在编写一个简单的HTTP服务器,我需要解析传入的请求。
假设我读过以下GET /file HTTP/1.1
我需要将其拆分为GET
/file
我尝试过多种方法,似乎无法使用任何方法。
问题是服务器在以下while循环中以块的形式读取传入的请求:
char echoBuffer[RCVBUFSIZE];
int recvMsgSize;
if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
DieWithError("recv() failed");
while (recvMsgSize > 0) {
if ((recvMsgSize = recv(clntSocket, echoBuffer, RCVBUFSIZE, 0)) < 0)
DieWithError("recv() failed");
}
我在循环中尝试了以下方法:
char *token;
for (i = 0; i < 3; i++){
switch (i) {
case 0:
token = strtok(echoBuffer, "/");
printf("%s\n", token[i]);
case 1:
token = strtok(echoBuffer, "HTTP");
printf("%s\n", token[i]);
}
}
但所有这些打印都是GET
几次。
我尝试过定义字符串char *echoString
并使用strcat()
这只是一起失败,我希望因为缓冲区是一个char数组。
那么我的选择是什么?
答案 0 :(得分:0)
如上述评论中所述,您需要
recv()
调用请注意,因为任何strtok()
系列函数(包括我在下面的实现)都依赖于静态变量,它们不是线程安全的!在这里要特别小心......
#include <stdio.h>
#include <stdlib.h>
/* a dummy recv() implementation that returns the size
* of received buffer */
size_t recv_(int s, void *buf, size_t len, int flags) {
len=0;
char *tmp=buf;
for (; *tmp; ++tmp, ++len)
;
return len;
}
/* Modified version of zstring_strtok
* first call -> zstrint_strtok(char *str, char *delim, int len)
* consecutive calls -> zstrint_strtok(NULL, char *delim,0)
*/
char *zstring_strtok(char *str, const char *delim, int len) {
static char *static_str=0; /* var to store last address */
int index=0, strlength=len; /* integers for indexes */
int found = 0; /* check if delim is found */
/* delimiter cannot be NULL
* if no more char left, return NULL as well
*/
if (delim==0 || (str == 0 && static_str == 0))
return 0;
if (str == 0)
str = static_str;
/* get length of string */
if (len==0)
while(str[strlength])
strlength++;
else
strlength=len;
/* find the first occurance of delim */
for (index=0;index<strlength;index++)
if (str[index]==delim[0]) {
found=1;
break;
}
/* if delim is not contained in str, return str */
if (!found) {
static_str = 0;
return str;
}
/* check for consecutive delimiters
*if first char is delim, return delim
*/
if (str[0]==delim[0]) {
static_str = (str + 1);
return (char *)delim;
}
/* terminate the string
* this assignmetn requires char[], so str has to
* be char[] rather than *char
*/
str[index] = '\0';
/* save the rest of the string */
if ((str + index + 1)!=0)
static_str = (str + index + 1);
else
static_str = 0;
return str;
}
int main()
{
char response[]="GET /file HTTP/1.1";
char *buf;
int recv_msg_size;
buf=malloc(256);
if((recv_msg_size=recv_(0,response,0,0)) > 0){
buf=zstring_strtok(response," ",recv_msg_size);
do{
printf("%s\n",buf);
} while(buf=zstring_strtok(NULL," ",0));
}
return 0;
}
zstring_strtok()
功能是the zString library, a BSD licensed string processing library for C中zstring_strtok()
的修改版本。
上面的recv_()
函数是recv()
系统调用的虚拟替换,只是为了使您的exmaple代码更易于阅读。在我的系统(FreeBSD 10.2-RELEASE)上,recv(3)被定义为
ssize_t
recv(int s, void *buf, size_t len, int flags);
以上示例的输出是
% ./recv
GET
/file
HTTP/1.1