cpp socket accept but not receive on Ajax GET - c++

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

Related

C/C++: socket() creation fails in the loop, too many open files

I am implementing a client-server TCP socket application. Client is on an OpenWRT Linux router (C based) and writes some data on the socket repeatedly and in a loop at some frequency rate. The Server is on a Linux Ubuntu machine (C/C++ based) and reads data in a loop according to data arrival speed.
Problem: Running the Server and then Client, server keeps reading new data. Both sides work well until the number of data deliveries (# of connections) reaches 1013. After that, the Client stuck at socket(AF_INET,SOCK_STREAM,0) with socket creation failed...: Too many open files. Apparently, the number of open fd approaches ulimit -n = 1024 on client.
I put the snippets of the code which shows the loop structures for Server.cpp and Client.c:
Server.c:
// TCP Socket creation stuff over here (work as they should):
// int sock_ = socket() / bind() / listen()
while (1)
{
socklen_t sizeOfserv_addr = sizeof(serv_addr_);
fd_set set;
struct timeval timeout;
int connfd_;
FD_ZERO(&set);
FD_SET(sock_, &set);
timeout.tv_sec = 10;
timeout.tv_usec = 0;
int rv_ = select(sock_ + 1, &set, NULL, NULL, &timeout);
if(rv_ == -1){
perror("select");
return 1;
}
else if(rv_ == 0){
printf("Client disconnected.."); /* a timeout occured */
close (connfd_);
close (sock_);
}
else{
connfd_ = accept (sock_,(struct sockaddr*)&serv_addr_,(socklen_t*)&sizeOfserv_addr);
if (connfd_ >= 0) {
int ret = read (connfd_, &payload, sizeof(payload)); /* some payload */
if (ret > 0)
printf("Received %d bytes !\n", ret);
close (connfd_); /* Keep parent socket open (sock_) */
}else{
printf("Server acccept failed..\n");
close (connfd_);
close (stcp.sock_);
return 0;
}
}
}
Client.cpp:
while (payload_exist) /* assuming payload_exist is true */
{
struct sockaddr_in servaddr;
int sock;
if (sock = socket(AF_INET, SOCK_STREAM, 0) == -1)
perror("socket creation failed...\n");
int one = 1;
int idletime = 2;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &idletime, sizeof(idletime));
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.100.12");
servaddr.sin_port = htons(PORT); /* some PORT */
if (connect (sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0){
perror("connect failed...");
return 1;
}
write(sock, (struct sockaddr*)&payload, sizeof(payload)); /* some new payload */
shutdown(sock,SHUT_WR);
bool serverOff = false;
while (!serverOff){
if(read(sock, &res, sizeof(res)) < 0){
serverOff = true;
close(sock);
}
}
}
NOTE: payload is 800 bytes and always gets fully transmitted per one write action. Having both codes defined under int main(), the client keeps creating sockets and sending data, on the other side, server receives all and would automatically close() and leave if client terminates, due to using select(). If I don't terminate the Client, however, by checking some print logs, it is evident that Server successfully receives 1013 payloads before client crashes with socket creation failed...: Too many open files.
Update:
Following the point mentioned by Steffen Ullrich, it turned out that, the client socket fd has no leak, and the existence of a second fd in the original loop (which was left open) was making the ulimit exceed the limit.
if(read(sock, &res, sizeof(res)) < 0){
serverOff = true;
close(sock); /********* Not actually closing sock *********/
}
Your check for end of connection is wrong.
read returns 0 if the other side has shut down the connection and <0 only on error.
if (sock = socket(AF_INET, SOCK_STREAM, 0) == -1)
perror("socket creation failed...\n");
Given the precedence of operators in C this basically says:
sock = ( socket(AF_INET, SOCK_STREAM, 0) == -1) )
if (sock) ...
Assuming that socket(...) will not return an error but a file descriptor (i.e. >=0) the comparison will be false and thus this essentially says sock = 0 while leaking a file descriptor if the fd returned by socket was >0.

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.

C++ Reconnect TCP Server to Client after Client restart

I want to implement a 'flexible' TCP connection where I can randomly shutdown and restart both the Server and the Client. The other one should then automatically detect the shutdown and enter try to reconnect. I successfully implemented this s.t. I can shutdown and restart the server. The client discovers the shutdown (via recv(...) == 0) and then closes the connection (it therefore closes the sockets close(this->sockfd_) and close(this->newsockfd_)).
Unfortunately I am not able to get this working the other way around. I initialize the server (using the class constructor) the following way:
tcpServer::tcpServer(int _port) {
this->sockfd_ = -1;
this->port_ = _port;
this->connected_ = false;
if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
this->dieWithError("ERROR opening Socket");
else
printf("-> Port %d: Socket opened\n", this->port_);
// get rid of "address already in use" error message
int yes = 1;
setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
/* assign values to the fields of struct sockaddr_in */
bzero((char *) &this->serv_addr_, sizeof(this->serv_addr_));
this->serv_addr_.sin_family = AF_INET;
this->serv_addr_.sin_port = htons(this->port_);
this->serv_addr_.sin_addr.s_addr = INADDR_ANY;
/* bind the socket to an address */
if (bind(this->sockfd_, (struct sockaddr *) &this->serv_addr_, sizeof(this->serv_addr_)) < 0) {
printf("-> Port %d:", this->port_);
this->dieWithError("ERROR on binding");
}
printf("-> Binding successful. Start TCP client in new terminal\n");
fflush(stdout);
/* listen for connections and accept a connection */
listen(this->sockfd_, 5);
this->clilen_ = sizeof(this->cli_addr_);
if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
this->dieWithError("Error on accept");
else {
printf("-> Connection established\n");
this->connected_ = true;
}
}
So once the server detects that the connection is closed, it enters a loop where it tries to reconnect using the following code:
void tcpServer::connect() {
if (this->sockfd_ == -1) {
/* create socket */
if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
this->dieWithError("ERROR opening Socket");
else
printf("-> Port %d: Socket opened\n", this->port_);
// get rid of "address already in use" error message
int reuse_address = 1;
setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &reuse_address, sizeof(int));
/* listen for connections and accept a connection */
listen(this->sockfd_, 5);
this->clilen_ = sizeof(this->cli_addr_);
if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
this->dieWithError("Error on accept");
else {
printf("-> Connection established\n");
this->connected_ = true;
}
}
}
Some simple debugging output tells me that in the reconnect-mode, the server gets stuck in the
accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_) call. Another observation I made is that the client does not shut down properly (via ctrl-c), i.e., it gets stuck in a loop somewhere and does not properly close the connection.
Since I am a total beginner with the TCP stuff, I would be very happy if someone could point me to the right direction. Thank you.

Server socket finishes when client closes connection

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.

select listen socket always succeeds

I am doing a toy server-client project(on linux) where multiple clients connect to server and do remote execution on server. What I have is a select() call which is supposed to tell me when a socket is readable. This is for both listen and accept new connection. Below I am posting a snippet.
int main() {
int sockfd;
fd_set readfds;
struct sockaddr_in serv_addr,cli_addr;
struct timeval tv;
socklen_t clilen = sizeof(cli_addr);
sockfd=socket(AF_INET, SOCK_STREAM, 0);
//setsockopt(sockid,IPPROTO_IPV6,IPV6_V6ONLY,(char *)&yes,sizeof(yes));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr =inet_addr("127.0.0.1");// INADDR_ANY;
serv_addr.sin_port = htons(40000);
if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
perror("bind");
}
while(1)
{
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
tv.tv_sec=2;
tv.tv_usec=500000;
int result =select(sockfd+1,&readfds,NULL,NULL,&tv);
if(result<0) {
exit(-1);
}
else if(result>0) {
if(FD_ISSET(sockfd,&readfds)) {
//int newsockfd =accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
int newsockfd =accept(sockfd,NULL,NULL);
if(newsockfd<0) {
perror("accept");
}
}
}
}
return 0;
}
But the select in the above code is always succeeding irrespective of the presence of any client and the accept is throwing error:
"accept: Invalid argument" and keep on looping, select is not even waiting for the timeout. Can someone please explain what is problem with my code. Am I not using select the right way it is supposed to be used(I am using it for the first time)?
You forgot to call listen after bind.