How to make mutiple socket writes with one active socket connection to an express web server?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am trying to do multiple write requests with one active socket connection to an express server running on localhost. I am making a http request to a express web server running on localhost. The message is sent like so:
GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive
I made sure to include "Connection: keep-alive" header in the message (though, it's not necessary since I am using HTTP/1.1).
Code for sending request
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. %dnn", sent);
}
Driver code
char* dummy[80] = {"GET", "localhost", "3001", "/temp", "?sensorId=1&value=71"};
setMessage(a, dummy);
makeRequest(a);
getResponse(&a);
sleep(2);
makeRequest(a);
getResponse(&a);
I am expected to get two "71" on my express server end, but I am only receiving the first one. The first write request gives a successful response back, but the next one sends no response (http connection is kept alive).
The two write commands do return the expected number of bytes written.
The makeRequest(a) is a wrapper to call sendRequest() as shown above.
The getRequest(&a) is a wrapper to call read on the socket.
UPDATE
The getResponse(&a) simply makes a call to the following code
#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;
}
UPDATE 2
Having called getResponse(&a)after each makeRequest(a) call results in the following response:
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:
However, if a getResponse(&a) is called after the two makeRequest(a) then both writes occur successfully, but I get the following for 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
javascript c express
add a comment |
I am trying to do multiple write requests with one active socket connection to an express server running on localhost. I am making a http request to a express web server running on localhost. The message is sent like so:
GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive
I made sure to include "Connection: keep-alive" header in the message (though, it's not necessary since I am using HTTP/1.1).
Code for sending request
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. %dnn", sent);
}
Driver code
char* dummy[80] = {"GET", "localhost", "3001", "/temp", "?sensorId=1&value=71"};
setMessage(a, dummy);
makeRequest(a);
getResponse(&a);
sleep(2);
makeRequest(a);
getResponse(&a);
I am expected to get two "71" on my express server end, but I am only receiving the first one. The first write request gives a successful response back, but the next one sends no response (http connection is kept alive).
The two write commands do return the expected number of bytes written.
The makeRequest(a) is a wrapper to call sendRequest() as shown above.
The getRequest(&a) is a wrapper to call read on the socket.
UPDATE
The getResponse(&a) simply makes a call to the following code
#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;
}
UPDATE 2
Having called getResponse(&a)after each makeRequest(a) call results in the following response:
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:
However, if a getResponse(&a) is called after the two makeRequest(a) then both writes occur successfully, but I get the following for 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
javascript c express
AContent-length
header that specifies the correct size of the request body ought to help.
– John Bollinger
Jan 2 at 21:47
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
1
I can explain the behavior when you comment out the firstgetResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: yourgetResponse()
function is not suited for use with a persistent connection.
– John Bollinger
Jan 3 at 1:21
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03
add a comment |
I am trying to do multiple write requests with one active socket connection to an express server running on localhost. I am making a http request to a express web server running on localhost. The message is sent like so:
GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive
I made sure to include "Connection: keep-alive" header in the message (though, it's not necessary since I am using HTTP/1.1).
Code for sending request
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. %dnn", sent);
}
Driver code
char* dummy[80] = {"GET", "localhost", "3001", "/temp", "?sensorId=1&value=71"};
setMessage(a, dummy);
makeRequest(a);
getResponse(&a);
sleep(2);
makeRequest(a);
getResponse(&a);
I am expected to get two "71" on my express server end, but I am only receiving the first one. The first write request gives a successful response back, but the next one sends no response (http connection is kept alive).
The two write commands do return the expected number of bytes written.
The makeRequest(a) is a wrapper to call sendRequest() as shown above.
The getRequest(&a) is a wrapper to call read on the socket.
UPDATE
The getResponse(&a) simply makes a call to the following code
#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;
}
UPDATE 2
Having called getResponse(&a)after each makeRequest(a) call results in the following response:
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:
However, if a getResponse(&a) is called after the two makeRequest(a) then both writes occur successfully, but I get the following for 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
javascript c express
I am trying to do multiple write requests with one active socket connection to an express server running on localhost. I am making a http request to a express web server running on localhost. The message is sent like so:
GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive
I made sure to include "Connection: keep-alive" header in the message (though, it's not necessary since I am using HTTP/1.1).
Code for sending request
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. %dnn", sent);
}
Driver code
char* dummy[80] = {"GET", "localhost", "3001", "/temp", "?sensorId=1&value=71"};
setMessage(a, dummy);
makeRequest(a);
getResponse(&a);
sleep(2);
makeRequest(a);
getResponse(&a);
I am expected to get two "71" on my express server end, but I am only receiving the first one. The first write request gives a successful response back, but the next one sends no response (http connection is kept alive).
The two write commands do return the expected number of bytes written.
The makeRequest(a) is a wrapper to call sendRequest() as shown above.
The getRequest(&a) is a wrapper to call read on the socket.
UPDATE
The getResponse(&a) simply makes a call to the following code
#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;
}
UPDATE 2
Having called getResponse(&a)after each makeRequest(a) call results in the following response:
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:
However, if a getResponse(&a) is called after the two makeRequest(a) then both writes occur successfully, but I get the following for 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
javascript c express
javascript c express
edited Jan 3 at 2:02
rated2016
asked Jan 2 at 19:39
rated2016rated2016
5610
5610
AContent-length
header that specifies the correct size of the request body ought to help.
– John Bollinger
Jan 2 at 21:47
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
1
I can explain the behavior when you comment out the firstgetResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: yourgetResponse()
function is not suited for use with a persistent connection.
– John Bollinger
Jan 3 at 1:21
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03
add a comment |
AContent-length
header that specifies the correct size of the request body ought to help.
– John Bollinger
Jan 2 at 21:47
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
1
I can explain the behavior when you comment out the firstgetResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: yourgetResponse()
function is not suited for use with a persistent connection.
– John Bollinger
Jan 3 at 1:21
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03
A
Content-length
header that specifies the correct size of the request body ought to help.– John Bollinger
Jan 2 at 21:47
A
Content-length
header that specifies the correct size of the request body ought to help.– John Bollinger
Jan 2 at 21:47
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
1
1
I can explain the behavior when you comment out the first
getResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: your getResponse()
function is not suited for use with a persistent connection.– John Bollinger
Jan 3 at 1:21
I can explain the behavior when you comment out the first
getResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: your getResponse()
function is not suited for use with a persistent connection.– John Bollinger
Jan 3 at 1:21
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03
add a comment |
1 Answer
1
active
oldest
votes
I am trying to do multiple write requests with one active socket connection to an express server running on localhost.
Your receiveResponse()
function is not suited for use with a persistent (a.k.a. keep-alive) connection. Consider this fragment:
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);
Under what conditions does the loop terminate? Well, it terminates
if the receive buffer fills.
if
read()
returns a negative number, signaling an error.if
read()
returns 0, signaling end-of-file.
No other in-program condition causes the loop to terminate. Each of the first two possibilities triggers an error message and program termination, so if one of those were occurring then you would know (right?). Therefore, you must be seeing the last alternative ... or are you?
What exactly does end-of-file mean for a socket? As with any other file, it means that no more data can (ever) be obtained from the socket -- for natural reasons, else you would get an error instead. For a socket specifically, that means the remote peer has closed the connection, or at least has shut down its output side of that connection. And that's exactly what does not happen with a persistent connection, at least not quickly. When it eventually does happen, if you wait that long, the connection is gone -- you need to establish a new one to receive another response.
So,
I am expected to get two "71" on my express server end, but I am only
receiving the first one.
This is because the second request is not attempted until after the server closes the connection (the read loop blocks until then), at which point the second request cannot be delivered, or at minimum, no response to it can be received.
The first write request gives a successful
response back, but the next one sends no response (http connection is
kept alive).
The response to the first request is successfully received as expected. No response to the second is received because the second is not successfully delivered to the server, which is also consistent with what you see on the server side. I am at a loss to explain why the client does not emit an error message in this case, which is why I pressed you for more information, but it is certain that getResponse()
will return successfully at most once for any given connection, and it is improbable that any further requests can successfully be sent over the connection after that.
You commented,
if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated.
That's perfectly natural. You're using a persistent connection, so the response to each successfully delivered request is readable from the same connection. In this case, you defer reading the data until after both requests have been sent, so the server responds to both.
To handle persistent connections, an HTTP client needs to be able to recognize message boundaries other than at EOF. The standard way to do this is by parsing the response headers as they come in, finding and parsing the content-length among them, and after reaching the response body, reading the number of bytes given by the content length.
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012209%2fhow-to-make-mutiple-socket-writes-with-one-active-socket-connection-to-an-expres%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I am trying to do multiple write requests with one active socket connection to an express server running on localhost.
Your receiveResponse()
function is not suited for use with a persistent (a.k.a. keep-alive) connection. Consider this fragment:
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);
Under what conditions does the loop terminate? Well, it terminates
if the receive buffer fills.
if
read()
returns a negative number, signaling an error.if
read()
returns 0, signaling end-of-file.
No other in-program condition causes the loop to terminate. Each of the first two possibilities triggers an error message and program termination, so if one of those were occurring then you would know (right?). Therefore, you must be seeing the last alternative ... or are you?
What exactly does end-of-file mean for a socket? As with any other file, it means that no more data can (ever) be obtained from the socket -- for natural reasons, else you would get an error instead. For a socket specifically, that means the remote peer has closed the connection, or at least has shut down its output side of that connection. And that's exactly what does not happen with a persistent connection, at least not quickly. When it eventually does happen, if you wait that long, the connection is gone -- you need to establish a new one to receive another response.
So,
I am expected to get two "71" on my express server end, but I am only
receiving the first one.
This is because the second request is not attempted until after the server closes the connection (the read loop blocks until then), at which point the second request cannot be delivered, or at minimum, no response to it can be received.
The first write request gives a successful
response back, but the next one sends no response (http connection is
kept alive).
The response to the first request is successfully received as expected. No response to the second is received because the second is not successfully delivered to the server, which is also consistent with what you see on the server side. I am at a loss to explain why the client does not emit an error message in this case, which is why I pressed you for more information, but it is certain that getResponse()
will return successfully at most once for any given connection, and it is improbable that any further requests can successfully be sent over the connection after that.
You commented,
if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated.
That's perfectly natural. You're using a persistent connection, so the response to each successfully delivered request is readable from the same connection. In this case, you defer reading the data until after both requests have been sent, so the server responds to both.
To handle persistent connections, an HTTP client needs to be able to recognize message boundaries other than at EOF. The standard way to do this is by parsing the response headers as they come in, finding and parsing the content-length among them, and after reaching the response body, reading the number of bytes given by the content length.
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
add a comment |
I am trying to do multiple write requests with one active socket connection to an express server running on localhost.
Your receiveResponse()
function is not suited for use with a persistent (a.k.a. keep-alive) connection. Consider this fragment:
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);
Under what conditions does the loop terminate? Well, it terminates
if the receive buffer fills.
if
read()
returns a negative number, signaling an error.if
read()
returns 0, signaling end-of-file.
No other in-program condition causes the loop to terminate. Each of the first two possibilities triggers an error message and program termination, so if one of those were occurring then you would know (right?). Therefore, you must be seeing the last alternative ... or are you?
What exactly does end-of-file mean for a socket? As with any other file, it means that no more data can (ever) be obtained from the socket -- for natural reasons, else you would get an error instead. For a socket specifically, that means the remote peer has closed the connection, or at least has shut down its output side of that connection. And that's exactly what does not happen with a persistent connection, at least not quickly. When it eventually does happen, if you wait that long, the connection is gone -- you need to establish a new one to receive another response.
So,
I am expected to get two "71" on my express server end, but I am only
receiving the first one.
This is because the second request is not attempted until after the server closes the connection (the read loop blocks until then), at which point the second request cannot be delivered, or at minimum, no response to it can be received.
The first write request gives a successful
response back, but the next one sends no response (http connection is
kept alive).
The response to the first request is successfully received as expected. No response to the second is received because the second is not successfully delivered to the server, which is also consistent with what you see on the server side. I am at a loss to explain why the client does not emit an error message in this case, which is why I pressed you for more information, but it is certain that getResponse()
will return successfully at most once for any given connection, and it is improbable that any further requests can successfully be sent over the connection after that.
You commented,
if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated.
That's perfectly natural. You're using a persistent connection, so the response to each successfully delivered request is readable from the same connection. In this case, you defer reading the data until after both requests have been sent, so the server responds to both.
To handle persistent connections, an HTTP client needs to be able to recognize message boundaries other than at EOF. The standard way to do this is by parsing the response headers as they come in, finding and parsing the content-length among them, and after reaching the response body, reading the number of bytes given by the content length.
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
add a comment |
I am trying to do multiple write requests with one active socket connection to an express server running on localhost.
Your receiveResponse()
function is not suited for use with a persistent (a.k.a. keep-alive) connection. Consider this fragment:
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);
Under what conditions does the loop terminate? Well, it terminates
if the receive buffer fills.
if
read()
returns a negative number, signaling an error.if
read()
returns 0, signaling end-of-file.
No other in-program condition causes the loop to terminate. Each of the first two possibilities triggers an error message and program termination, so if one of those were occurring then you would know (right?). Therefore, you must be seeing the last alternative ... or are you?
What exactly does end-of-file mean for a socket? As with any other file, it means that no more data can (ever) be obtained from the socket -- for natural reasons, else you would get an error instead. For a socket specifically, that means the remote peer has closed the connection, or at least has shut down its output side of that connection. And that's exactly what does not happen with a persistent connection, at least not quickly. When it eventually does happen, if you wait that long, the connection is gone -- you need to establish a new one to receive another response.
So,
I am expected to get two "71" on my express server end, but I am only
receiving the first one.
This is because the second request is not attempted until after the server closes the connection (the read loop blocks until then), at which point the second request cannot be delivered, or at minimum, no response to it can be received.
The first write request gives a successful
response back, but the next one sends no response (http connection is
kept alive).
The response to the first request is successfully received as expected. No response to the second is received because the second is not successfully delivered to the server, which is also consistent with what you see on the server side. I am at a loss to explain why the client does not emit an error message in this case, which is why I pressed you for more information, but it is certain that getResponse()
will return successfully at most once for any given connection, and it is improbable that any further requests can successfully be sent over the connection after that.
You commented,
if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated.
That's perfectly natural. You're using a persistent connection, so the response to each successfully delivered request is readable from the same connection. In this case, you defer reading the data until after both requests have been sent, so the server responds to both.
To handle persistent connections, an HTTP client needs to be able to recognize message boundaries other than at EOF. The standard way to do this is by parsing the response headers as they come in, finding and parsing the content-length among them, and after reaching the response body, reading the number of bytes given by the content length.
I am trying to do multiple write requests with one active socket connection to an express server running on localhost.
Your receiveResponse()
function is not suited for use with a persistent (a.k.a. keep-alive) connection. Consider this fragment:
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);
Under what conditions does the loop terminate? Well, it terminates
if the receive buffer fills.
if
read()
returns a negative number, signaling an error.if
read()
returns 0, signaling end-of-file.
No other in-program condition causes the loop to terminate. Each of the first two possibilities triggers an error message and program termination, so if one of those were occurring then you would know (right?). Therefore, you must be seeing the last alternative ... or are you?
What exactly does end-of-file mean for a socket? As with any other file, it means that no more data can (ever) be obtained from the socket -- for natural reasons, else you would get an error instead. For a socket specifically, that means the remote peer has closed the connection, or at least has shut down its output side of that connection. And that's exactly what does not happen with a persistent connection, at least not quickly. When it eventually does happen, if you wait that long, the connection is gone -- you need to establish a new one to receive another response.
So,
I am expected to get two "71" on my express server end, but I am only
receiving the first one.
This is because the second request is not attempted until after the server closes the connection (the read loop blocks until then), at which point the second request cannot be delivered, or at minimum, no response to it can be received.
The first write request gives a successful
response back, but the next one sends no response (http connection is
kept alive).
The response to the first request is successfully received as expected. No response to the second is received because the second is not successfully delivered to the server, which is also consistent with what you see on the server side. I am at a loss to explain why the client does not emit an error message in this case, which is why I pressed you for more information, but it is certain that getResponse()
will return successfully at most once for any given connection, and it is improbable that any further requests can successfully be sent over the connection after that.
You commented,
if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated.
That's perfectly natural. You're using a persistent connection, so the response to each successfully delivered request is readable from the same connection. In this case, you defer reading the data until after both requests have been sent, so the server responds to both.
To handle persistent connections, an HTTP client needs to be able to recognize message boundaries other than at EOF. The standard way to do this is by parsing the response headers as they come in, finding and parsing the content-length among them, and after reaching the response body, reading the number of bytes given by the content length.
answered Jan 3 at 3:08
John BollingerJohn Bollinger
85k74279
85k74279
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
add a comment |
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
Awesome, this helped a lot!
– rated2016
Jan 3 at 18:10
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
So, it's the while loop with read that is preventing the attempt of second request. The wait block caused the connection to be lost? Either the connection was active enough to send the second request, but not enough to get a response, or not active enough to send the request in the first place. Similarly, I am confused why an error was not thrown from either write or read calls.
– rated2016
Jan 3 at 18:28
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
The read call returns 0 bytes once the connection has closed from the other end and not the usual end-of-file? With persistent connection, my code for reading the response is waiting too long causing the connection to be lost. So, I can't have persistent connection where I send 1 request now and another 30 minutes later?
– rated2016
Jan 3 at 18:41
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
@rated2016, the connection being closed is the usual end-of-file for a socket. Until then, the remote side may send more data, so even if there isn't any data to read now, there may be some later, therefore the end of the file has not been reached (or at least it cannot be recognized).
– John Bollinger
Jan 3 at 20:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012209%2fhow-to-make-mutiple-socket-writes-with-one-active-socket-connection-to-an-expres%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
A
Content-length
header that specifies the correct size of the request body ought to help.– John Bollinger
Jan 2 at 21:47
I am doing a GET request which believe does not require a content-length? Nonetheless, I have tried that approach but did not work.
– rated2016
Jan 3 at 0:20
Found something interesting and seems to be working now. So, if I comment the first getResponse(&a) call both writes go in successfully. Now, the last response call returns a string where the two responses are concatenated. WOW. I will update my post with what my getResponse(&a) looks like. Would be great if someone can explain why it is that.
– rated2016
Jan 3 at 0:34
1
I can explain the behavior when you comment out the first
getResponse()
call, but to fully answer the question I need a more complete explanation of exactly what you do in the original case, and what result you observe, including any error messages. I'm not prepared to believe that the description already given is complete. A hint: yourgetResponse()
function is not suited for use with a persistent connection.– John Bollinger
Jan 3 at 1:21
I have added the outputs for both scenarios. Here are links to my files containing the whole: pastebin.com/u3R4WVMA pastebin.com/J59RRkC0. Thanks!
– rated2016
Jan 3 at 2:03