Sockets C套接字服务器:读取所有长度未知的XMLHttpRequest的正确方法是什么?
我有一个用C编写的简单XMLHttpRequest处理程序。它读取和处理来自浏览器中运行的JavaScript XMLHttpRequest发送的请求 父进程接受传入连接,并为每个传入连接派生一个子进程来读取和处理数据 它适用于大多数请求,但在某些情况下,如果请求长度超过2K字节,则会失败,这显然与客户端和服务器之间的网络基础设施有关。我假设请求被分解为浏览器和套接字服务器之间的多个数据包 我无法更改请求格式,但我可以看到正在发送的请求并验证内容。数据是一个带有编码URI的“GET”,该URI包含一个“type”字段。如果类型为“file”,则请求可能长达3K,否则最多为几百字节文件请求很少-用户提供要写入服务器上文件的配置数据。所有其他请求都可以正常工作,任何小于2K的“文件”请求都可以正常工作 在这种情况下,确保我拥有所有数据的首选技术是什么 下面是父级接受连接并派生子级非阻塞版本的部分:Sockets C套接字服务器:读取所有长度未知的XMLHttpRequest的正确方法是什么?,sockets,xmlhttprequest,packet,recv,Sockets,Xmlhttprequest,Packet,Recv,我有一个用C编写的简单XMLHttpRequest处理程序。它读取和处理来自浏览器中运行的JavaScript XMLHttpRequest发送的请求 父进程接受传入连接,并为每个传入连接派生一个子进程来读取和处理数据 它适用于大多数请求,但在某些情况下,如果请求长度超过2K字节,则会失败,这显然与客户端和服务器之间的网络基础设施有关。我假设请求被分解为浏览器和套接字服务器之间的多个数据包 我无法更改请求格式,但我可以看到正在发送的请求并验证内容。数据是一个带有编码URI的“GET”,该URI包
for (hit = 1;; hit++) {
length = sizeof(cli_addr);
if ((socketfd = accept4(listensd, (struct sockaddr *) &cli_addr, &length, SOCK_NONBLOCK)) < 0){
//if ((socketfd = accept(listensd, (struct sockaddr *) &cli_addr, &length)) < 0){
exit(3);
}
if ((pid = fork()) < 0) {
exit(3);
} else {
if (pid == 0) { /* child */
//(void) close(listensd);
childProcess(socketfd, hit); /* never returns. Close listensd when done*/
} else { /* parent */
(void) close(socketfd);
}
}
}
如果类型为“文件”,则可能有更多数据。子进程永远不会获取其余的数据。如果套接字阻塞,则第二次读取尝试将挂起。如果套接字是非阻塞的,如下面的代码段所示,则所有后续读取都返回-1,错误为“Resource Temporary unavailable”,直到超时:
// It's a file. Could be broken into multiple blocks. Try second read
sleep(1);
ret = recv(socketfd, &recv_data[len], BUFSIZE, 0); // read request
while (ret != 0){
if(ret > 0){
recv_data[len+ret] = 0;
len += ret;
} else {
sleep(1);
}
ret = recv(socketfd, &recv_data[len], BUFSIZE, 0); // read request
}
我预计read在客户端关闭连接时会返回0,但这并没有发生。GET请求只有头部而没有正文,几乎总是这样,所以只要有了请求头部,您就拥有客户端发送的所有内容,当你读到一个空白行,即两次返回,并且不早或晚,你知道你读了整个请求标题 <>如果客户端只发送一个部分,而没有空行,则应该等待其余部分。如果时间太长,我会暂停并拒绝整个请求
顺便说一句,还有一些浏览器,可能还有一些代理,URL长度限制在2000个字符左右。当数据无法立即使用时,非阻塞套接字会引发错误。它基本上意味着稍后再试。您可以使用select来确定套接字是否已准备好读/写,或者不使用非阻塞套接字。如果从未获得更多数据,则可能是服务器未正确发送数据。提供一个可复制的示例以进行进一步调试。如果您从未获得更多数据,则可能是服务器未正确发送数据,或者更可能是您未正确读取/处理数据,因此在到达请求结束时不知道何时停止读取。显示的代码显然不是从XMLHttpRequest客户端读取请求的正确方法。因此,当到达请求结束时,不知道何时停止读取。-没错,但我也不知道什么时候我需要读更多。读取的返回值似乎没有帮助。是否有我缺少的套接字选项或内容标题技巧?
// It's a file. Could be broken into multiple blocks. Try second read
sleep(1);
ret = recv(socketfd, &recv_data[len], BUFSIZE, 0); // read request
while (ret != 0){
if(ret > 0){
recv_data[len+ret] = 0;
len += ret;
} else {
sleep(1);
}
ret = recv(socketfd, &recv_data[len], BUFSIZE, 0); // read request
}