Javascript 如何通过与express web服务器的一个活动套接字连接进行多个套接字写入?

Javascript 如何通过与express web服务器的一个活动套接字连接进行多个套接字写入?,javascript,c,express,Javascript,C,Express,我正试图通过一个活动套接字连接到本地主机上运行的express服务器来执行多个写请求。我正在向本地主机上运行的express web服务器发出http请求。该消息是这样发送的: GET /temp?sensorId=1&value=71 HTTP/1.1 Content-Type: text/html; charset=utf-8 Connection: keep-alive 我确保在消息中包含Connection:keep-alive头,但这并不是必需的,因为我使用的是HTTP/1.

我正试图通过一个活动套接字连接到本地主机上运行的express服务器来执行多个写请求。我正在向本地主机上运行的express web服务器发出http请求。该消息是这样发送的:

GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive
我确保在消息中包含Connection:keep-alive头,但这并不是必需的,因为我使用的是HTTP/1.1

发送请求的代码

void sendRequest (char** message, int* socket_ref) {
int total = strlen(*message);
int bytes, sent = 0;
do {
    bytes = write(*socket_ref, *message + sent, total - sent);
    if (bytes < 0) {
        perror("ERROR writing message to socket yo");
        exit(EXIT_FAILURE);
    }
    if (bytes == 0) break;
    sent += bytes;
} while (sent < total);

   printf("Data sent. %d\n\n", sent);
}
我希望在我的express服务器端得到两个71,但我只收到第一个。第一个写请求返回一个成功的响应,但下一个请求不发送响应http连接保持活动状态

这两个write命令返回预期的写入字节数

makeRequesta是调用sendRequest的包装器,如上所示。 getRequest&a是在套接字上调用read的包装器

更新 getResponse&a只调用以下代码

#define RESPONSE_SIZE 4096
char* receiveResponse(int* socket_ref) {
char* response = malloc(RESPONSE_SIZE);
int total, bytes, received = 0;

memset(response, 0, RESPONSE_SIZE);
total = RESPONSE_SIZE - 1;
do {
    bytes = read(*socket_ref, response + received, total - received);
    if (bytes < 0) {
        perror("ERROR reading response from socket yo");
        exit(EXIT_FAILURE);
    }
    if (bytes == 0) break;
    received += bytes;
} while (received < total);
if (received == total) {
    perror("ERROR storing complete response from socket yo");
    exit(EXIT_FAILURE);
}
return response;
但是,如果在两个makeRequesta之后调用getResponse&a,则两次写入都会成功进行,但我得到以下响应:

Data sent. 125

Response:
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-d2PTd7kl/AFtn95E/ir6IzKjD9I"
Date: Thu, 03 Jan 2019 01:51:12 GMT
Connection: keep-alive

GOOD
Data sent. 125

Response:
Data sent. 125

Data sent. 125

Response:
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-d2PTd7kl/AFtn95E/ir6IzKjD9I"
Date: Thu, 03 Jan 2019 02:00:43 GMT
Connection: keep-alive

GOODHTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-d2PTd7kl/AFtn95E/ir6IzKjD9I"
Date: Thu, 03 Jan 2019 02:00:43 GMT
Connection: keep-alive

GOOD
我正试图通过一个活动套接字连接到本地主机上运行的express服务器来执行多个写请求

您的ReceiverResponse函数不适合与持续a.k.a.保持活动连接一起使用。考虑这个片段:

循环在什么条件下终止?嗯,它终止了

如果接收缓冲区已满

如果read返回负数,则表示错误

如果read返回0,则表示文件结束

没有其他程序内条件导致循环终止。前两种可能性中的每一种都会触发错误消息和程序终止,因此,如果其中一种情况发生,那么您就知道了,对吗?。因此,你一定看到了最后一个选择。。。还是你

对于套接字,文件结尾到底意味着什么?与任何其他文件一样,这意味着无法从套接字获取更多的数据——出于自然原因,否则会出现错误。具体来说,对于套接字,这意味着远程对等方已经关闭了连接,或者至少已经关闭了该连接的输出端。这正是持久连接不会发生的情况,至少不会很快发生。当它最终发生时,如果你等待那么久,连接就消失了——你需要建立一个新的连接来接收另一个响应

所以

我希望在我的express服务器端得到两个71,但我只是 接收第一个

这是因为在服务器关闭连接之前,不会尝试第二个请求。在此之前,读取循环会阻塞,此时无法传递第二个请求,或者至少无法接收到对该请求的响应

第一个写请求给出了一个成功的 响应返回,但下一个没有发送响应,http连接已断开 还活着

第一个请求的响应按预期成功接收。没有收到对第二个的响应,因为第二个未成功传递到服务器,这也与您在服务器端看到的一致。我无法解释为什么在这种情况下客户端不发出错误消息,这就是为什么我要求您提供更多信息,但可以肯定的是,对于任何给定的连接,getResponse最多只会成功返回一次,并且此后不可能再通过连接成功发送任何请求

你评论说,

如果我注释第一个getResponse&一个调用,那么两次写入都会成功进入。现在,最后一个响应调用返回一个字符串,其中两个响应连接在一起

这很自然。您使用的是持久连接,因此对每个成功传递的请求的响应都可以从同一个连接读取。在这种情况下,您延迟读取数据,直到两个请求都被发送之后,因此服务器对这两个请求都做出响应


要处理持久连接,HTTP客户端需要能够识别除EOF之外的消息边界。实现这一点的标准方法是在响应头进入时对其进行解析,查找并解析其中的内容长度,然后在到达响应体之后,读取内容长度给定的字节数。

指定请求正文正确大小的内容长度标头应该会有所帮助。我正在执行一个GET请求,相信它不需要内容长度?尽管如此,我还是尝试过这种方法,但没有成功。我发现了一些有趣的东西,现在似乎正在发挥作用。因此,如果我注释第一个getResponse&一个调用,那么两次写入都会成功进入。现在,最后一个响应调用返回一个字符串,其中两个响应连接在一起。哇!我会用我的getResponse&a更新我的帖子。如果有人能解释为什么会这样,那就太好了。我可以在你发表评论时解释你的行为
第一个getResponse调用,但要完全回答这个问题,我需要更完整地解释您在原始情况下的具体操作,以及您观察到的结果,包括任何错误消息。我不准备相信已经给出的描述是完整的。提示:getResponse函数不适合用于持久连接。我已经为这两种情况添加了输出。以下是指向包含以下内容的我的文件的链接:。谢谢太棒了,这帮了大忙!因此,带read的while循环阻止了第二个请求的尝试。等待块导致连接丢失?连接的活动程度足以发送第二个请求,但不足以获得响应,或者连接的活动程度不足以发送第一个请求。类似地,我很困惑为什么写调用或读调用都没有抛出错误。一旦连接从另一端关闭,读调用返回0字节,而不是通常的文件端?使用持久连接时,我读取响应的代码等待时间过长,导致连接丢失。所以,如果我现在发送一个请求,30分钟后再发送另一个请求,我就无法建立持久连接了?@rated2016,正在关闭的连接是套接字的文件结尾。在此之前,远程端可能会发送更多数据,因此,即使现在没有任何数据可读取,以后也可能会有一些数据可读取,因此尚未到达文件结尾,或者至少无法识别文件结尾。
Data sent. 125

Data sent. 125

Response:
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-d2PTd7kl/AFtn95E/ir6IzKjD9I"
Date: Thu, 03 Jan 2019 02:00:43 GMT
Connection: keep-alive

GOODHTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 4
ETag: W/"4-d2PTd7kl/AFtn95E/ir6IzKjD9I"
Date: Thu, 03 Jan 2019 02:00:43 GMT
Connection: keep-alive

GOOD
int total, bytes, received = 0;

memset(response, 0, RESPONSE_SIZE);
total = RESPONSE_SIZE - 1;
do {
    bytes = read(*socket_ref, response + received, total - received);
    if (bytes < 0) {
        perror("ERROR reading response from socket yo");
        exit(EXIT_FAILURE);
    }
    if (bytes == 0) break;
    received += bytes;
} while (received < total);