【问题标题】:With winsock, how receive POST Http message from IE使用winsock,如何接收来自IE的POST Http消息
【发布时间】:2012-01-17 14:28:11
【问题描述】:

我有一个带有函数 receiveNetworkData(...) 的 C++ 应用程序。此功能对于下载 Internet 上的任何其他页面非常有用。这个 f-c 的正文在这里:

int receiveNetworkData(int socket, string *receive_data) {
  int size, receive_size = 0;
  char buf[BUFSIZE];

  clearBuffer(buf);
  receive_data->clear();
  while (((size = recv(socket, buf, BUFSIZE-1, 0)) != 0) && (size != -1)) {
    receive_size += size;
    *receive_data += buf;
    clearBuffer(buf);
  }

  if (size == -1) return -1;
  return receive_size;
}

但是当我尝试使用此功能从 IE 获取 http 请求时。 recv 函数阻塞了程序。 我发现 IE 在两个 TCP 数据包中发送 POST 请求。这是真的,但有时 IE 只发送一个数据包。现在recv只是等待tird数据包。我不知道如何识别来自IE的消息结束。

这是从 IE9 发送请求的 JavaScript 代码。

  http_zadost.open('POST', 'http://localhost:8001/', true);      
  http_zadost.setRequestHeader("Content-length", 5);
  http_zadost.setRequestHeader("Connection", "close");  
  http_zadost.send("check");

【问题讨论】:

  • 我不明白你的意思。套接字的一些选项?
  • 您在实现 HTTP 服务器吗?如果你是,我对你的“......对下载互联网上的任何其他页面非常有用”的声明感到困惑。

标签: c++ xmlhttprequest winsock


【解决方案1】:

所有套接字在创建时都阻塞。这意味着从它们中读取之类的操作将阻塞,直到调用得到满足。

recv 的情况下,如果套接字阻塞,那么函数将阻塞执行,直到接收到所有请求的数据。在您的情况下,recv 将在 BUFSIZE-1 字节被放入缓冲区或发生错误之前不会返回。

要使用 winsock 使套接字成为非阻塞的,您可以像这样使用函数 ioctlsocket

u_long mode = 1;
ioctlsocket(sock, FIONBIO, &mode);

如果mode 不为零,则套接字将更改为非阻塞模式。

编辑

重新阅读您的问题后,我发现问题在于您不知道来自浏览器 JavaScript 的请求何时结束。来自Wikipedia关于HTTP协议的文章:

请求消息包含以下内容:

  • 请求行
  • 标题
  • 空行。
  • 可选消息正文。

请求行和标头都必须以(即,回车后跟换行符)结尾。空行必须只包含空格,不能包含其他空格。

您必须阅读直到获得完整的标题,即您收到一个空行。然后您还应该知道是否有要读取的消息正文(有一个非零的“Content-length”标头)以及它有多大。

请注意,您仍然需要在我的回答中如上所述让套接字非阻塞。

【讨论】:

  • 谢谢你,我现在找到了关于它的教程。我希望,现在一切都会好起来的。 win32developer.com/tutorial/winsock/winsock_tutorial_4.shtm
  • A 的代码与客户端接收数据的许多示例完全相同,但是当我尝试从 IE 接收数据时出现问题。
  • 是的,这就是问题所在。对不起我的英语。
  • 对我来说有趣的是,当我尝试通过 recv() 下载谷歌页面时。当 recv() 返回 0 时下载完成。但在 IE func 的情况下。 recv() 返回第一个数据包(标头)的大小和第二个数据包(正文)的下一个返回大小,然后去接收第三个数据包。但是没有第三个数据包,recv() 被阻塞。我写了一个新函数,比较来自标题和正文的内容长度,如果正文在缓冲区中具有正确的长度->不再调用 recv()。但是为什么这个问题只存在于 IE 中。
  • @Lodhart 网络服务器在发送请求响应后立即关闭连接,从recv 返回0 表示连接已关闭。浏览器在发送请求后必须保持连接打开,以便接收响应。某些 HTTP 标头(例如 "Connection")当然可以改变这种行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 2011-11-06
  • 1970-01-01
  • 2021-09-02
相关资源
最近更新 更多