What is the most efficient way to perform multiple socket writes using a single active socket connection to an Express web server?

Attempting to perform multiple write requests using a single active socket connection to an express server running on localhost. This is done by making an HTTP request to an express web server on localhost with the following message:

GET /temp?sensorId=1&value=71 HTTP/1.1
Content-Type: text/html; charset=utf-8
Connection: keep-alive

Ensured that the "Connection: keep-alive" header is included in the message, although not necessary when using HTTP/1.1.

Function for sending requests:

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);
}

Driver code snippet:

 char* dummy[80] = {"GET", "localhost", "3001", "/temp", "?sensorId=1&value=71"};
        setMessage(a, dummy);
        makeRequest(a);

        getResponse(&a);
        sleep(2);

        makeRequest(a);
        getResponse(&a);

Expecting to receive two "71" on the express server end, but only receiving the first one. The second write request does not elicit a response even though the HTTP connection is kept alive.

Both write commands return the expected number of bytes written.

The makeRequest(a) is a wrapper calling sendRequest() as shown above.
The getRequest(&a) is a wrapper invoking read on the socket.

UPDATE The getResponse(&a) simply invokes 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 After calling getResponse(&a) following each makeRequest(a) call, the responses are as follows:

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, calling getResponse(&a) after both makeRequest(a) calls result in both writes being successful, but the response is as follows:

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

Answer №1

I'm attempting to execute multiple write requests using a single active socket connection to an express server on localhost.

The receiveResponse() function is not designed for use with a persistent (or keep-alive) connection. Here's a snippet to consider:

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 circumstances does the loop end? It ends

  • if the receive buffer is full.

  • if read() returns a negative value, indicating an error.

  • if read() returns 0, indicating end-of-file.

No other conditions within the program cause the loop to end. The first two possibilities result in an error message and program termination, so you would be aware if they were occurring, right? Therefore, the last scenario must be happening... or is it?

What does end-of-file signify for a socket? Like any other file, it means that no more data can be obtained from the socket -- for obvious reasons, otherwise an error would occur. For a socket specifically, it suggests that the remote peer has either closed the connection or shut down its output side of the connection. This is contrary to what typically occurs with a persistent connection, at least not immediately. When it eventually does happen, if you wait that long, the connection is lost -- necessitating the establishment of a new one to receive another response.

Thus,

I anticipate receiving two "71" values on my express server end, but I am only receiving the first.

This discrepancy is due to the fact that the second request is not attempted until after the server terminates the connection (the read loop blocks until then), preventing the second request from being delivered or, at best, receiving no response to it.

The first write request results in a successful response, but the subsequent one does not receive a response (as the HTTP connection remains open).

The anticipated response to the first request is successfully received, as expected. The lack of response to the second request is due to its failure to reach the server, aligning with observations on the server side. I cannot explain why the client does not generate an error message in this scenario, prompting my request for additional information. Nevertheless, it is certain that getResponse() will return successfully at most once per connection, and the successful delivery of any further requests over the same connection is unlikely.

You mentioned,

If I comment out the first getResponse(&a) call, both writes are successful. However, the final response call concatenates the two responses into a single string.

This behavior is expected. Given your use of a persistent connection, the response to each successfully delivered request can be read from the same connection. By delaying the data read until after both requests are sent, the server can respond to both.

To manage persistent connections, an HTTP client must recognize message boundaries beyond EOF. This is typically achieved by parsing response headers as they arrive, extracting and parsing the content-length, and subsequently reading the specified number of bytes once the response body is reached.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ajax Syntax Error: Unexpected Token U

I have been struggling all day with an issue while trying to send json data via ajax to Express. Here is how my ajax code looks like: $('#saveClause').click(function () { var username = document.getElementById('postUserName').inne ...

the buttonclick won't pause the timer

I'm having trouble with the timer function when a button is clicked. The startpause() method sets the start and stop timers, but when I click the button rapidly multiple times, the timer starts to jump by 2-3 seconds. It seems like more than one timer ...

The deletion of Webpack Clean- /public/js has been successfully completed

I am utilizing the clean-webpack-plugin to empty the contents of my public/js directory. https://www.npmjs.com/package/clean-webpack-plugin Despite trying various methods, I keep encountering the message /public/js has been removed plugins: [ new CleanW ...

Rendering images from Laravel's storage folder in a React component

When uploading an image from a React frontend to a Laravel backend, I encountered an issue where the uploaded image path was saved in the database but the image wouldn't display. React code ` useEffect(() => { axiosClient .g ...

The POST request is being made multiple times within the Express/Angular application, though it is unclear whether the issue lies

Take a look at my Angular code Component Section onSubmit(formValue: any) { console.log("Form Value = " + JSON.stringify(formValue, null, 4)); let newRegisteredUser = { firstName : formValue.firstName, lastNam ...

What is the method for populating a dropdown using ajax in the Jade template engine?

Looking to dynamically populate a dropdown based on the selection of another dropdown. Here's the code snippet: script. var b_name = []; function jsFunction() { var client = document.getElementById('drop_client'); var c_name = cli ...

Integrating Cache and Resolved Promises in Angular's UI-Router: A Comprehensive Guide

I have been working on an Angular app where I used to load all data before displaying any page through the ui-router resolve. However, I found that some data was being repeated, so I decided to cache the data using localStorage. Now I'm trying to figu ...

"Encountered issues during compiling: X ERROR found at line 9 in the Header.js file, spanning from characters

An error occurred while compiling the module. The following message was displayed: Module not found: Error: Can't resolve '@mui/icons-material/Search' in 'C:\Users\pande\Documents\slack-clone\src\component ...

Can you explain the distinction between using angular.copy() and simply using an assignment (=) to assign values

When a button is clicked, I want to assign certain values using the event parameter. Here is the code: $scope.update = function(context) { $scope.master = context; }; The $scope.master has been assigned the values of user. Recently, I came across th ...

Show the button when the mouse moves over the image

Here is the snippet of code I am working with: <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server"> <script src="Js/jquery.min.js"></script> <script type="text/javascript"> $(document).r ...

How to dynamically change the content of the <header> in Nextjs depending on the loaded component

I recently finished creating a app/components/Header.js component. export function Header() { return <> <header className="w-full h-14 grid grid-cols-12 bg-gray-50 text-black dark:bg-gray-900 dark:text-white"> <div ...

Is there a way to modify Bootstrap tabs when they are hovered over?

This may seem like a simple question, but I've been struggling to figure it out. I'm attempting to have the bootstrap tabs switch when the mouse hovers over them. <div class="container"> <nav class="nav nav-tabs" ...

Text printed by a thread initialized with pthread_create is not appearing on screen

I am currently studying threads and POSIX thread from the book Modern Operating Systems by Tanenbaum. As part of my learning, I am experimenting with the following code: #include <stdio.h> #include <stdlib.h> #include <pthread.h> void * ...

The paragraph tag remains unchanged

I am currently working on developing a feature that saves high scores using local storage. The project I'm working on is a quiz application which displays the top 5 scores at the end, regardless of whether the quiz was completed or not. However, I&apo ...

An uncaught runtime error has occurred: TypeError - subSector.map is not a valid function

I'm encountering a challenge when attempting to map through JSON data retrieved from a fictitious API. The process works smoothly when there is more than one data item, but I encounter an error when there is only a single object. Below is the code sn ...

Reposition the span element to the right of the div tag

I need help adjusting the positioning of the elements in this HTML code. How can I move the span element with the image to the right of the div tag? Here is the code snippet: <div style='width:600px;padding-top: 2px;padding-bottom: 1px'& ...

Tips for enabling mouse functionality while utilizing PointerLockControls

I'm currently working on a 3D art gallery using Three.js and PointerLockControls for navigation. My goal is to have the artwork on the gallery walls clickable, triggering a pop-up window with additional information. However, it seems that PointerLock ...

Effective strategies for managing form submissions with React and Typescript

As I dive into refactoring my code to TypeScript, especially as I am still getting accustomed to it, I find myself pondering about the HTML element types with React events. This has led me to rethink how I approach form creation and submission event handli ...

Unusual Behavior Observed in JavaScript Map Reduce

var t = [-12, 57, 22, 12, -120, -3]; t.map(Math.abs).reduce(function(current, previousResult) { return Math.min(current, previousResult); }); // returns 3 t.map(Math.abs).reduce(Math.min); // returns NaN I'm puzzled as to why the second variant ...

The best scenarios for implementing next() and return next() functions in Node.js

Case Study: Let's analyze the code snippet below, extracted from a node web application. app.get('/users/:id?', function(req, res, next){ var id = req.params.id; if (id) { // perform certain actions } else { next ...