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.
Related
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'?
I am implementing Web Services in CPP program on WinCE.
I put a web server (HTTP), listenning on port 8080, and unitary tests works (using postman).
I put in a html page, a simple ajax request (GET) to get back a JSON array.
Init web server :
struct sockaddr_in serv_addr;
int optlen = 0;
struct timeval vtime;
SCK_ListenServerSocket = socket(AF_INET, SOCK_STREAM, 0);
if (SCK_ListenServerSocket < 0)
return (WBS_Service_Unavailable_503);
// Set receive timeout
optlen = sizeof(struct timeval);
if(getsockopt(SCK_ListenServerSocket, SOL_SOCKET, SO_RCVTIMEO, (char *) &vtime, &optlen) == -1)
{
closesocket(SCK_ListenServerSocket);
return (WBS_Service_Unavailable_503);
}
else
{
vtime.tv_sec = SCK_SRV_RECV_MS_TIMEOUT; // ms
vtime.tv_usec = 0;
if(setsockopt(SCK_ListenServerSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *) &vtime, optlen) == -1)
{
closesocket(SCK_ListenServerSocket);
return (WBS_Service_Unavailable_503);
}
}
memset((void *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if (bind(SCK_ListenServerSocket, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
closesocket(SCK_ListenServerSocket);
SCK_ListenServerSocket = -1;
return (WBS_Service_Unavailable_503);
}
if(listen(SCK_ListenServerSocket, 1) < 0)
{
closesocket(SCK_ListenServerSocket);
SCK_ListenServerSocket = -1;
return (WBS_Service_Unavailable_503);
}
return ret;
In a thread, that function is called :
accept_socket = accept(SCK_ListenServerSocket, NULL, NULL);
if(accept_socket < 0)
n = 0;
else
{
n = recv(accept_socket, &buffer[0], 512, 0); //Read 512 bytes
DO THE WORK
}
The problem:
When I launch the web page on Chrome, the socket is opened corretly but never received. I don't know why. When I use POSTMAN it works like a charm.
Thank you for helping me.
EDIT : In that blocking socket operation, accept is called but recv is blocking. Launching a lot of request unblocks the recv, but recv response is 0 when it fails.
When I load the website on WinCE (the same target), the problem appears. When the website is loaded from my computer, and only the request is sent, no problem
I'm trying to create a server socket with C++ in order to accept one client connection at a time. The program successfully creates the server socket and waits for incoming connections but when a connection is closed by the client the program would loop endlessly. Otherwise if the connection is interrupted it would keep waiting for new connections as expected. Any idea why this is happening? Thanks
This is my C++ server code:
int listenfd, connfd, n;
struct sockaddr_in servaddr, cliaddr;
socklen_t clilen;
pid_t childpid;
char mesg[1000];
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(32000);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 1024);
while (true) {
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
if ((childpid = fork()) == 0) {
close (listenfd);
while (true) {
n = recvfrom(connfd, mesg, 1000, 0, (struct sockaddr *)&cliaddr, &clilen);
sendto(connfd, mesg, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
mesg[n] = 0;
printf("%d: %s \n", n, mesg);
if (n <= 0) break;
}
close(connfd);
}
}
For some reason when the client closes the connection the program would keep printing -1: even with the if-break clause..
You never close connfd in parent process (when childpid != 0), and you do not properly terminate child process that will try to loop. Your if block should look like :
if ((childpid = fork()) == 0) {
...
close(connfd);
exit(0);
}
else {
close(connfd);
}
But as you say you want to accept one connection at a time, you can simply not fork.
And as seen in other answers :
do not use mesg[n] without testing n >= 0
recvfrom and sendto are overkill for TCP simply use recv and send (or even read and write)
mesg[n] = 0;
This breaks when n<0, ie. socket closed
The problem is your "n" and recvfrom. You are having a TCP client so the recvfrom won't return the correct value.
try to have a look on :
How to send and receive data socket TCP (C/C++)
Edit 1 :
Take note that you do the binding not connect() http://www.beej.us/guide/bgnet/output/html/multipage/recvman.html
means there is an error in recieving data, errno will be set accordingly, please try to check the error flag.
you've written a TCP server, but you use recvfrom and sendto which are specific for connection-less protocols (UDP).
try with recv and send. maybe that might help.
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.
I have a socket that listens on some port.
I send the SIGSTOP signal to the thread that waits on the port (using accept) and terminate it. then I close the fd of the socket that I waited on. But for the next run of my project it doe's not allow me to listen on that port again.
My program is in C++ under linux.
What should I do?
Some parts of my code are:
Thread 1:
void* accepter(void *portNo) {
int newsockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
}
struct sockaddr_in server;
bzero((char *) & server, sizeof (server));
server.sin_family = AF_INET;
server.sin_port = htons(*(int*) portNo);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr *) & server, sizeof (struct sockaddr_in)) < 0) {
perror("ERROR on binding");
}
listen(sockfd, 50);
while (true) {
struct sockaddr_in client;
socklen_t clientLen = sizeof (struct sockaddr_in);
newsockfd = accept(sockfd, (struct sockaddr *) & client, &clientLen);
if (accepterFlag) {
break;
}
if (getpeername(newsockfd, (sockaddr *) & client, &clientLen) == -1) {
perror("getpeername() failed");
}
sem_wait(setSem);
FD_SET(newsockfd, &set);
if (maxFd < newsockfd) {
maxFd = newsockfd;
}
sem_post(setSem);
}
Thread 2:
listenerFlag = true;
accepterFlag = true;
sleep(1);
pthread_kill(listenerThread, SIGSTOP);
pthread_kill(accepterThread, SIGSTOP);
close(sockfd);
sem_wait(setSem);
for (int i = 1; i <= maxFd; i++) {
if (FD_ISSET(i, &set)) {
close(i);
}
}
sem_post(setSem);
Thank you.
Did you know that sockets are typically kept in a kind of limbo for a minute or two after you've finished listening on them to prevent communications intended for the previous process coming to yours? It's called the 'TIME_WAIT' state.
If you want to override that behaviour use setsockopt to set the SO_REUSEADDR flag against the socket before listening on it.
I think the problem is that you have not properly closed the socket and/or your program.The socket probably still exists in the OS. check it with something like nestat -an. You should also check if your process has exited. If it has correctly ended, it should have closed your socket.
What you should do is :
interrupt your thread with a signal.
when interrupted your thread should cleanly close the socket before the end.
then you can cleanly exit from your program.
my2cents,