Example of c++ client and node.js server - c++

I have a problem... I'm trying to connect my client written in c++ to my server written in nodejs but I couldn't do. How can i receive data in the server? With this code I receive the client connection but not the data that it sends. I will appreciate a simple example to send and receive data from a c++ client and nodejs server.
This is my client.cpp
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
//valread = read( sock , buffer, 1024);
//printf("%s\n",buffer );
return 0;
}
This is my server.js
const server = require('http').createServer();
const io = require('socket.io')(server, {
path: '/test',
serveClient: false,
// below are engine.IO options
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
server.on('connection', function (client) {
console.log("New connection");
});
server.on('data', function (client) {
console.log("New data");
});
server.on('close', () => {
console.log('Subscriber disconnected.');
});
server.listen(8080);

Your client program terminates faster than the server has time to read the data (the socket is closed before the system has time to send the output buffer). Put a 'sleep' (or any other waiting concept) before you exit and look what happens.
p.s. what is the return value of your 'send'?

Related

Why doesn't my UDP connection send messages even though there are no errors?

I took the UDP connection code from geeksforgeeks and made some changes as the code is problematic. I also took out some parts of it as I don't need my client to send an initial message. I just need the client to continuously receive 4 bytes of datagrams from the server.
The changes I made are mainly from:
Socket Programming Pointer Error
The problem I have now is that, as far as I know from my Python socket programming, a client would give an error if there is no port open to be connected, but my client seems to connect even though the server program is not running. However this is tcp that I am talking about. Is UDP supposed to act like this?
Second problem is that server sends a message even though there is no client and I assume this is the UDP process as there is no 3 way handshake and server assumes there is a client listening.
Basically it seems like server sends messages but client can't receive them even though both programs run without error.
The program can be in C or C++ as I am using cpp compiler and do not have a preference as long as it works.
server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int n;
socklen_t len;
len = sizeof(cliaddr); //len is value/resuslt
sendto(sockfd, (const char *)hello, strlen(hello),
0, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
client:
// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n;
socklen_t len;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
Udp is very unreliable in such cases as it does not require ACK response packages from the server. Because of that, the program will not throw any errors even if the data isn't received. I would recommend using TCP instead or (if you are testing the code on a local network) check that the firewall ports your program uses are open both on client and server side.
You should know that UDP is not a reliable protocol: it just sends datagrams and never thinks about whether the other side has received it or not. If you want a reliable connection, you can choose TCP or a reliable protocol over UDP such as QUIC, kcp.
I think you should learn some basic network knowledge while progamming, such as from the books 《Unix Network Programming》and《TCP/IP Illustrated》, or you will meet many problems and don't know how to solve them.

Server socket not working properly while running in background

I have two process: Server and client. Both are different sockets. Initially I execute server socket by ./server and then ./client.
But I wanted that server process should listen in background always for the request from client.
Then inplace of executing ./server, i used ./server & . This works fine in the first client call and then when i tried to connect to server it give connection failed
server.cpp
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char *hello = "Hello from server";
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_addr.s_addr = inet_addr("192.168.2.184");
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
send(new_socket , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
return 0;
}
client.cpp
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "192.168.2.184", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock , hello , strlen(hello) , 0 );
printf("Hello message sent\n");
valread = read( sock , buffer, 1024);
printf("%s\n",buffer );
}
You have one misunderstanding with the bash comand lines ampersand (&) operator.
The trailing ampersand directs the shell to run the command in the background, that is, it is forked and run in a separate sub-shell, as a job, asynchronously. The shell will immediately return the return status of 0 for true and continue as normal, either processing further commands in a script or returning the cursor focus back to the user in a Linux terminal.
So, you invoke the program in the background and you can continue immediately to work in the shell.
But this does not mean that your program continues to run. When your program reaches its end, then its process will be terminated. The program stops.
So, what you could do (but definitely should not do) is, to call your program from the shell in a loop.
The correct way is, to build a loop in your server program and continue to accept connections. But then you need either to fork new processes or use a kind of factory, to create new TCP classes or whatever necessary to handle the requests from the client.
All this is not that simple, because the control flow of the program needs to be well designed. Linux has functions like (p)select, (p)poll or epoll to support with such atcivities.
There are also designpatterns like Reactor/Proactor/ACT available. You could implement that. But better to use an existing library.
But for testing purposes you approach is ok.

How to Test and Run a Client Server Program in C++ using Eclipse

I am trying to get started with UDP and would like to test and debug some client server programs.
I am using an Eclipse IDE with cygwin64 as a compiler.
I have found some example client server programs from here: https://www.geeksforgeeks.org/udp-server-client-implementation-c/
I would like to be able to run the example to get me started on learning about UDP client servers.
The example code is as follows:
Server
// Server side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
int len, n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,
&len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello),
0, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
Client
// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 8080
#define MAXLINE 1024
// Driver code
int main() {
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
int n, len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
close(sockfd);
return 0;
}
I have tried opening up two different eclipse workbenches and running both the codes, but it is not running as expected and it is saying that the messages have been sent but I have not been able to receive them on the client or server.
I definitely would like to stick with c/c++ and try to get this working in eclipse if it's possible.
If anyone has any advice on how I can be able to see some results or anything that could get me started with this, it would be much appreciated. Thank you!
Problem
You have not set the address of the server correctly in the client code.
servaddr.sin_addr.s_addr = INADDR_ANY;
is meaningless when sending (Why would you want to send to any available address? You want to send to the server.) and is rejected by sendto. You would have seen this if you'd checked the return value. Always check the return value, even for UDP communications. Sure there are a million reasons why a packet won't arrive with UDP that you can't detect at the time of sendto, but it's good to know that the network stack actually accepted the message even if a grue subsequently devours the packet in one of the dark corners of the Internet. A sending error you can do something about, like perror and then fix the code accordingly. A grue, not so much. You'll have to make a protocol robust enough to retransmit or otherwise survive the loss of the packet.
Solution
Get the server's address structure with getaddrinfo.
Replace
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
with something more like
struct addrinfo hints;
struct addrinfo *hostlist;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
hints.ai_protocol = IPPROTO_UDP;
if (getaddrinfo("Server Name or Address Goes Here",
PORT, // this needs to be a char *, not an integer
&hints,
&hostlist))
{
// handle error
exit(EXIT_FAILURE);
}
PORT in this case needs to be a char *, so instead of
#define PORT 8080
use
constexpr char const * PORT = "8080";
You can leave out the constexpr if your compiler is old and doesn't support it.
Then when you go to send, iterate through the hostlist until you find a host that responds. Since you've probably narrowed the servers down to exactly one candidate, this is probably overkill, but you might as well get into practice doing things right. The alternative sucks when systems start getting complicated.
struct addrinfo *curhost;
for (curhost = hostlist; curhost != NULL; curhost = curhost->ai_next)
{
int rval = sendto(sockfd,
(const char *) hello,
strlen(hello),
0,
curhost->ai_addr,
curhost->ai_addrlen);
if (rval> 0) // always check return codes. Programmers are lazy.
// They wouldn't have gone to the effort of putting
// it there if it wasn't important.
{
if server responds
do protocol stuff to complete transaction
break;
}
}
freeaddrinfo(hostlist); // thou shalt not leak resources.
if (curhost == nullptr)
{
notify user that no server was willing to talk
}
Documentation for getaddrinfo.

Not able to send data between UDP client in matlab and server in linux

I have UDP program in matlab in one machine and UDP in cpp in other machine. I am able to send data from cpp code to matlab , by running cpp code as client and matlab code as server. When I tried running matlab as client and cpp as server I am not able to send the data to cpp.In Both the above cases programms are running in two different machines.I tried matlab as client and cpp as server in same machine then its worked.
my cpp code
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "port.h"
#define BUFSIZE 2048
int
main(int argc, char **argv)
{
struct sockaddr_in myaddr; /* our address */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen; /* # bytes received */
int fd; /* our socket */
unsigned char buf[BUFSIZE]; /* receive buffer */
/* create a UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket\n");
return 0;
}
/* bind the socket to any valid IP address and a specific port */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(SERVICE_PORT);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
/* now loop, receiving data and printing what we received */
for (;;) {
printf("waiting on port %d\n", SERVICE_PORT);
recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
printf("received %d bytes\n", recvlen);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("received message: \"%s\"\n", buf);
}
}
/* never exits */
}
Posting the answer from the comments here for visibility:
Since the programs work when run on the same computer, but not when run on separate computers, that points to a firewall issue (meaning the computer is blocking inbound traffic). In Linux, iptables (that's what the firewall is called) can be temporarily disabled per the instructions at: https://www.cyberciti.biz/faq/turn-on-turn-off-firewall-in-linux/
If that solves the problem, don't forget to turn iptables back on. Then just add an exception in iptables for your program similar to these instructions: https://help.ubuntu.com/community/IptablesHowTo#Allowing_Incoming_Traffic_on_Specific_Ports

changing a program to become a service?

i want to create a application that can run as a service and also another program (in c++) that can communicate with it. Basically i want the program to send messages to the service and the service just echoes them back to the program
sample output of program would be something like this:
Please input your message: hello
Receive response from server: hello
i have a very simple client server program in UDP that does this - server echoes back the messages the clients sends. so my question is can i change the server to become a service and change the client so it still communicates with the service? and if so how is this done?
i have never used code to create a service before so if someone can link any tutorials that would be great
heres the program i want to change:
server
void InitWinsock()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET socketS;
InitWinsock();
struct sockaddr_in local;
struct sockaddr_in from;
int fromlen = sizeof(from);
local.sin_family = AF_INET;
local.sin_port = htons(1234);
local.sin_addr.s_addr = INADDR_ANY;
socketS = socket(AF_INET,SOCK_DGRAM,0);
bind(socketS,(sockaddr*)&local,sizeof(local));
while (1)
{
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
printf("Waiting...\n");
if (recvfrom(socketS,buffer,sizeof(buffer),0,(sockaddr*)&from,&fromlen)!=SOCKET_ERROR)
{
printf("Received message from %s: %s\n",inet_ntoa(from.sin_addr), buffer);
sendto(socketS, buffer, sizeof(buffer), 0, (sockaddr*)&from, fromlen);
}
Sleep(500);
}
closesocket(socketS);
return 0;
}
client:
void InitWinsock()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET socketC;
InitWinsock();
struct sockaddr_in serverInfo;
int len = sizeof(serverInfo);
serverInfo.sin_family = AF_INET;
serverInfo.sin_port = htons(1234);
serverInfo.sin_addr.s_addr = inet_addr("127.0.0.1");
socketC = socket(AF_INET,SOCK_DGRAM,0);
while (1)
{
char buffer[1024];
ZeroMemory(buffer, sizeof(buffer));
printf("Please input your message: ");
scanf("%s", buffer);
if (strcmp(buffer,"exit") == 0)
break;
if (sendto(socketC, buffer, sizeof(buffer), 0, (sockaddr*)&serverInfo, len) != SOCKET_ERROR)
{
if (recvfrom(socketC, buffer, sizeof(buffer), 0, (sockaddr*)&serverInfo, &len) != SOCKET_ERROR)
{
printf("Receive response from server: %s\n", buffer);
}
}
}
closesocket(socketC);
return 0;
}
Use service example as sergmat said. Use the code in Svp.cpp, and put it into your server. Update the SVCNAME to your service name. Take the code in your _tmain and put it into the bottom of SvcInit where the TO_DO: Perform work until service stops is. Take out the while loop below it.
As an aside, your server has a Sleep(500) in the main loop. That's unnecessary as the server will block on the recv anyway.
To terminate the service, instead of using the ghSvcStopEvent, I'd just make the socket handle and some closing flag global, then set the flag and close the socket when you get the SERVICE_CONTROL_STOP signal.
You'll have a few more cleanup details but that should more than get you started...
Forget about changing your code, just use srvany.