Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets C套接字服务器:读取所有长度未知的XMLHttpRequest的正确方法是什么?_Sockets_Xmlhttprequest_Packet_Recv - Fatal编程技术网

Sockets C套接字服务器:读取所有长度未知的XMLHttpRequest的正确方法是什么?

Sockets C套接字服务器:读取所有长度未知的XMLHttpRequest的正确方法是什么?,sockets,xmlhttprequest,packet,recv,Sockets,Xmlhttprequest,Packet,Recv,我有一个用C编写的简单XMLHttpRequest处理程序。它读取和处理来自浏览器中运行的JavaScript XMLHttpRequest发送的请求 父进程接受传入连接,并为每个传入连接派生一个子进程来读取和处理数据 它适用于大多数请求,但在某些情况下,如果请求长度超过2K字节,则会失败,这显然与客户端和服务器之间的网络基础设施有关。我假设请求被分解为浏览器和套接字服务器之间的多个数据包 我无法更改请求格式,但我可以看到正在发送的请求并验证内容。数据是一个带有编码URI的“GET”,该URI包

我有一个用C编写的简单XMLHttpRequest处理程序。它读取和处理来自浏览器中运行的JavaScript XMLHttpRequest发送的请求

父进程接受传入连接,并为每个传入连接派生一个子进程来读取和处理数据

它适用于大多数请求,但在某些情况下,如果请求长度超过2K字节,则会失败,这显然与客户端和服务器之间的网络基础设施有关。我假设请求被分解为浏览器和套接字服务器之间的多个数据包

我无法更改请求格式,但我可以看到正在发送的请求并验证内容。数据是一个带有编码URI的“GET”,该URI包含一个“type”字段。如果类型为“file”,则请求可能长达3K,否则最多为几百字节文件请求很少-用户提供要写入服务器上文件的配置数据。所有其他请求都可以正常工作,任何小于2K的“文件”请求都可以正常工作

在这种情况下,确保我拥有所有数据的首选技术是什么

下面是父级接受连接并派生子级非阻塞版本的部分:

  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
}