c++ howto create and use a websocket to a remote machine
Hi, Thanks to an increasing number of grandchildren, as a retiree I have had little time in recent years to continue working on my C++ client for Basex. It therefore took a lot of time to find and fix a very persistent memory leak, but I finally succeeded. On a local machine, running basexserver, the entire server protocol can be handled without error messages. The only thing I couldn't test yet was the use of a websocket to a remote machine, and that now appears to be causing problems. On an old PC, I installed a minimal version of Fedora 43 that does not use GNOME. Basexserver runs without any problems and I can create new users in basexclient. Local use of my client does not cause any problems. But when I want to create a websocket to the test machine, I get the error message “setsockopt: Bad file descriptor”. After several attempts using the IP address instead of the machine name, both my laptop and the test PC crashed, and I had to reinstall basex. In C++, I use the following code to create a socket (the starting point for this code was Alexander Holupirek's C code “basexdbc.c”): BasexSocket & BasexSocket::CreateSocket (string host, string port) { // @suppress("Name convention for function") cout << __FUNCTION__ << " : " << host << " | " << port << " | " << endl; if (host.empty () || port.empty ()) { cout << "ERROR: Invalid hostname/port\n" << endl; exit(0); } /* if (host.empty () || port.empty ()) { Master_sfd = -1; return *this; } */ struct addrinfo hints; struct addrinfo * result = NULL, *rp; memset (&hints, 0, sizeof (struct addrinfo)); // Initialize hints hints.ai_family = AF_INET; // Accept both AF_INET and AF_INET6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; // Port must be specified as number int rc; rc = getaddrinfo (host.c_str (), port.c_str (), &hints, &result); if (rc != 0) perror (gai_strerror (rc)); for (rp = result; rp != NULL; rp = rp->ai_next) { // result is a linked list of address structures. Master_sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (Master_sfd == -1) continue; if (connect (Master_sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; // Try to connect. Return the first successfull connect or abort close (Master_sfd); } set_nonblock_flag (Master_sfd, 1); int opt = true; if (setsockopt (Master_sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt)) < 0) { perror ("setsockopt"); exit (EXIT_FAILURE); } if (rp == NULL) { warnx ("Can not connect to Basex server"); } freeaddrinfo (result); cout << "Master_sfd: " << Master_sfd << endl; return *this; }; Can anyone explain to me how I can successfully build a websocket to the test PC? Ben
Hi Ben, I can't speak to any C++ issues, but you might check if this is not just a permissions or network/firewall issue by: From the BaseX GUI on your laptop, execute: client:connect('test-pc', 1984, 'admin', '...') (:will return id if can connect else error :) Or from a laptop terminal window basexclient -n test-pc -p1984 Happy retirement. /Andy On Mon, 26 Jan 2026 at 16:37, Ben Engbers via BaseX-Talk < basex-talk@mailman.uni-konstanz.de> wrote:
Hi,
Thanks to an increasing number of grandchildren, as a retiree I have had little time in recent years to continue working on my C++ client for Basex. It therefore took a lot of time to find and fix a very persistent memory leak, but I finally succeeded. On a local machine, running basexserver, the entire server protocol can be handled without error messages. The only thing I couldn't test yet was the use of a websocket to a remote machine, and that now appears to be causing problems. On an old PC, I installed a minimal version of Fedora 43 that does not use GNOME. Basexserver runs without any problems and I can create new users in basexclient. Local use of my client does not cause any problems. But when I want to create a websocket to the test machine, I get the error message “setsockopt: Bad file descriptor”. After several attempts using the IP address instead of the machine name, both my laptop and the test PC crashed, and I had to reinstall basex. In C++, I use the following code to create a socket (the starting point for this code was Alexander Holupirek's C code “basexdbc.c”):
BasexSocket & BasexSocket::CreateSocket (string host, string port) { // @suppress("Name convention for function") cout << __FUNCTION__ << " : " << host << " | " << port << " | " << endl; if (host.empty () || port.empty ()) { cout << "ERROR: Invalid hostname/port\n" << endl; exit(0); } /* if (host.empty () || port.empty ()) { Master_sfd = -1; return *this; } */
struct addrinfo hints; struct addrinfo * result = NULL, *rp; memset (&hints, 0, sizeof (struct addrinfo)); // Initialize hints hints.ai_family = AF_INET; // Accept both AF_INET and AF_INET6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; // Port must be specified as number
int rc; rc = getaddrinfo (host.c_str (), port.c_str (), &hints, &result); if (rc != 0) perror (gai_strerror (rc));
for (rp = result; rp != NULL; rp = rp->ai_next) { // result is a linked list of address structures. Master_sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (Master_sfd == -1) continue; if (connect (Master_sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; // Try to connect. Return the first successfull connect or abort close (Master_sfd); } set_nonblock_flag (Master_sfd, 1); int opt = true; if (setsockopt (Master_sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt)) < 0) { perror ("setsockopt"); exit (EXIT_FAILURE); } if (rp == NULL) { warnx ("Can not connect to Basex server"); } freeaddrinfo (result); cout << "Master_sfd: " << Master_sfd << endl; return *this; };
Can anyone explain to me how I can successfully build a websocket to the test PC?
Ben
Hi basexclient -n test-pc -p 1984 failed so probably the problems are in the interface. Tomorrow I'll continue my search. Ben Op 26-01-2026 om 20:53 schreef Andy Bunce via BaseX-Talk:
Hi Ben,
I can't speak to any C++ issues, but you might check if this is not just a permissions or network/firewall issue by:
From the BaseX GUI on your laptop, execute:
|client:connect('test-pc', 1984, 'admin', '...') ||(:will return id if can connect else error :)|
Or from a laptop terminal window
|basexclient -n test-pc -p1984 |
Happy retirement.
/Andy
| |
On Mon, 26 Jan 2026 at 16:37, Ben Engbers via BaseX-Talk <basex- talk@mailman.uni-konstanz.de <mailto:basex-talk@mailman.uni- konstanz.de>> wrote:
Hi,
Thanks to an increasing number of grandchildren, as a retiree I have had little time in recent years to continue working on my C++ client for Basex. It therefore took a lot of time to find and fix a very persistent memory leak, but I finally succeeded. On a local machine, running basexserver, the entire server protocol can be handled without error messages. The only thing I couldn't test yet was the use of a websocket to a remote machine, and that now appears to be causing problems. On an old PC, I installed a minimal version of Fedora 43 that does not use GNOME. Basexserver runs without any problems and I can create new users in basexclient. Local use of my client does not cause any problems. But when I want to create a websocket to the test machine, I get the error message “setsockopt: Bad file descriptor”. After several attempts using the IP address instead of the machine name, both my laptop and the test PC crashed, and I had to reinstall basex. In C++, I use the following code to create a socket (the starting point for this code was Alexander Holupirek's C code “basexdbc.c”):
BasexSocket & BasexSocket::CreateSocket (string host, string port) { // @suppress("Name convention for function") cout << __FUNCTION__ << " : " << host << " | " << port << " | " << endl; if (host.empty () || port.empty ()) { cout << "ERROR: Invalid hostname/port\n" << endl; exit(0); } /* if (host.empty () || port.empty ()) { Master_sfd = -1; return *this; } */
struct addrinfo hints; struct addrinfo * result = NULL, *rp; memset (&hints, 0, sizeof (struct addrinfo)); // Initialize hints hints.ai_family = AF_INET; // Accept both AF_INET and AF_INET6 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_NUMERICSERV; // Port must be specified as number
int rc; rc = getaddrinfo (host.c_str (), port.c_str (), &hints, &result); if (rc != 0) perror (gai_strerror (rc));
for (rp = result; rp != NULL; rp = rp->ai_next) { // result is a linked list of address structures. Master_sfd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (Master_sfd == -1) continue; if (connect (Master_sfd, rp->ai_addr, rp->ai_addrlen) != -1) break; // Try to connect. Return the first successfull connect or abort close (Master_sfd); } set_nonblock_flag (Master_sfd, 1); int opt = true; if (setsockopt (Master_sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt)) < 0) { perror ("setsockopt"); exit (EXIT_FAILURE); } if (rp == NULL) { warnx ("Can not connect to Basex server"); } freeaddrinfo (result); cout << "Master_sfd: " << Master_sfd << endl; return *this; };
Can anyone explain to me how I can successfully build a websocket to the test PC?
Ben
-- Ben Engbers Grietjeshof 77 6721 VH Bennekom +31 6 23634840
Hi, It showed that with a Fedora 43 minimal install, ports 1984 and 8080 were closed in the firewall. After opening these ports, my code can also handle remote connections. I also asked Gemini is there were errors in my code. There were no real errors but Gemini suggested some improvements. I'll implement them and hopefully in one of the next few days I'll be able to upload a working beta version. Ben PS. While installing then server, I have been recording all the commands that were issued on the server. If someone wants to have that file, let me know. Op 26-01-2026 om 20:53 schreef Andy Bunce:
Hi Ben,
I can't speak to any C++ issues, but you might check if this is not just a permissions or network/firewall issue by:
From the BaseX GUI on your laptop, execute:
|client:connect('test-pc', 1984, 'admin', '...') ||(:will return id if can connect else error :)|
Or from a laptop terminal window
|basexclient -n test-pc -p1984 |
Happy retirement.
/Andy
👍 Andy Bunce reacted via Gmail <https://www.google.com/gmail/about/?utm_source=gmail-in-product&utm_medium=et&utm_campaign=emojireactionemail#app> On Wed, 28 Jan 2026 at 12:44, Ben Engbers <Ben.Engbers@be-logical.nl> wrote:
Hi,
It showed that with a Fedora 43 minimal install, ports 1984 and 8080 were closed in the firewall. After opening these ports, my code can also handle remote connections.
I also asked Gemini is there were errors in my code. There were no real errors but Gemini suggested some improvements. I'll implement them and hopefully in one of the next few days I'll be able to upload a working beta version.
Ben PS. While installing then server, I have been recording all the commands that were issued on the server. If someone wants to have that file, let me know.
Op 26-01-2026 om 20:53 schreef Andy Bunce:
Hi Ben,
I can't speak to any C++ issues, but you might check if this is not just a permissions or network/firewall issue by:
From the BaseX GUI on your laptop, execute:
|client:connect('test-pc', 1984, 'admin', '...') ||(:will return id if can connect else error :)|
Or from a laptop terminal window
|basexclient -n test-pc -p1984 |
Happy retirement.
/Andy
participants (2)
-
Andy Bunce -
Ben Engbers