Stuck in a timeout loop from using alarm(); - c++

I'm attempting to implement a GoBackN protocol and when the server drops a packet, my alarm waits 2 seconds before sending all previously sent packets.
The alarm works and waits 2 seconds, however after the first timeout, the state machine I'm using gets stuck in a loop and continues to timeout. I think it might be because errno is not getting reset, but I'm not sure.
#define TIMEOUT_SECS 2
#define MAXTRIES 10
int base = 0;
int windowSize = 7;
int sendFlag = 1;
int tries = 0;
int numPackets = 0;
packet *packetArray[30];
void addPacket(packet *p)
{
for (int i = 0; i < 30; i++)
{
if (packetArray[i])
{
continue;
}
else
{
packetArray[i] = p;
numPackets++;
break;
}
}
}
void
CatchAlarm(int ignored) /* Handler for SIGALRM */
{
tries += 1;
errno = 0;
}
void
DieWithError()
{
printf("error");
exit (1);
}
int
max(int a, int b)
{
if (b > a)
return b;
return a;
}
int
min(int a, int b)
{
if(b>a)
return a;
return b;
}
typedef enum
{
wait,
sendData,
timeout,
receiveData
} e_state;
int main(int argumentCount, char *argumentVariables[])
{
//Grabbing all input information.
struct hostent *emulatorName;
emulatorName = gethostbyname(argumentVariables[1]);
int receiveFromEmulator = atoi(argumentVariables[3]);
int sendToEmulator = atoi(argumentVariables[2]);
//Setting up UDP socket for receiving from emulator.
int receiveSocket = 0;
receiveSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//UDP socket configuration.
struct sockaddr_in receiveSocketStruct;
bzero((char *) &receiveSocketStruct, sizeof(receiveSocketStruct));
receiveSocketStruct.sin_family = AF_INET;
receiveSocketStruct.sin_port = htons(receiveFromEmulator);
receiveSocketStruct.sin_addr.s_addr = INADDR_ANY;
socklen_t receiveSocketLen = sizeof(receiveSocketStruct);
//Binding UDP socket so client can locate emulator.
bind(receiveSocket, (struct sockaddr *)&receiveSocketStruct, sizeof(receiveSocketStruct));
//Setting up UDP socket for sending to emulator.
int sendSocket = 0;
sendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//UDP socket configuration.
struct sockaddr_in sendSocketStruct;
bzero((char *) &sendSocketStruct, sizeof(sendSocketStruct));
sendSocketStruct.sin_family = AF_INET;
sendSocketStruct.sin_port = htons(sendToEmulator);
sendSocketStruct.sin_addr.s_addr = INADDR_ANY;
socklen_t sendSocketLen = sizeof(sendSocketStruct);
char buffer[1024];
std::ifstream infile (argumentVariables[4], std::ifstream::binary);
infile.seekg (0, infile.end);
int lengthOfFile = infile.tellg();
infile.seekg (0, infile.beg);
int totalPackets = 0;
int nextSeqNum = 0;
while(1)
{
if (lengthOfFile > 30)
{
bzero(buffer, 1024);
char * data = new char[1024];
infile.read(buffer, 30);
strncpy(data, buffer, 1024);
lengthOfFile -= 30;
if (nextSeqNum > 7)
{
nextSeqNum = 0;
}
addPacket(new packet(1, nextSeqNum, strlen(data), data));
totalPackets++;
nextSeqNum++;
}
else
{
bzero(buffer, 1024);
char * data = new char[1024];
infile.read(buffer, 30);
strncpy(data, buffer, 1024);
if (nextSeqNum > 7)
{
nextSeqNum = 0;
}
addPacket(new packet(1, nextSeqNum, strlen(data), data));
totalPackets++;
nextSeqNum++;
addPacket(new packet(3, nextSeqNum, 0, NULL));
totalPackets++;
break;
}
}
infile.close();
nextSeqNum = 0;
int packetsReceived;
int sentPackets;
int receive = 0;
char receivePayload[1024];
char sendPayload[1024];
struct sigaction myAction; /* For setting signal handler */
myAction.sa_handler = CatchAlarm;
if (sigfillset (&myAction.sa_mask) < 0) /* block everything in handler */
DieWithError ();
myAction.sa_flags = 0;
if (sigaction (SIGALRM, &myAction, 0) < 0)
DieWithError ();
e_state currentState = wait;
e_state previousState = wait;
while(1)
{
if (currentState == wait)
{
if (sendFlag == 1)
{
previousState = currentState;
currentState = sendData;
}
else
{
previousState = currentState;
currentState = receiveData;
}
}
else if (currentState == sendData)
{
if ((nextSeqNum < base + windowSize) && (nextSeqNum < totalPackets - 1))
{
//send packet with seqnum.
int sendPacket = 0;
bzero(sendPayload, 1024);
packet * sendpckt = packetArray[nextSeqNum];
sendpckt->serialize(sendPayload);
sendpckt->printContents();
sendPacket = sendto(sendSocket, sendPayload, sizeof(sendPayload), 0, (struct sockaddr *)&sendSocketStruct, sendSocketLen);
if (base == nextSeqNum)
{
alarm(0);
alarm(TIMEOUT_SECS);
}
nextSeqNum++;
}
else
{
sendFlag = 0;
previousState = currentState;
currentState = wait;
}
}
else if (currentState == timeout)
{
alarm(0);
alarm(TIMEOUT_SECS);
for(int counter = base; counter < nextSeqNum; counter++)
{
int sendPacket = 0;
bzero(sendPayload, 1024);
packet * sendpckt = packetArray[counter];
sendpckt->serialize(sendPayload);
sendpckt->printContents();
sendPacket = sendto(sendSocket, sendPayload, sizeof(sendPayload), 0, (struct sockaddr *)&sendSocketStruct, sendSocketLen);
}
sendFlag = 0;
previousState = currentState;
currentState = wait;
}
else if (currentState == receiveData)
{
bzero(receivePayload, 1024);
receive = (recvfrom(receiveSocket, receivePayload, sizeof(receivePayload), 0, (struct sockaddr *)&receiveSocketStruct, &receiveSocketLen));
if (errno == EINTR)
{
printf("timeout");
if (tries > MAXTRIES)
{
alarm(0);
break;
printf("recvfrom() failed.");
}
previousState = currentState;
currentState = timeout;
}
else
{
char buffer[1024];
bzero(buffer, 1024);
int receivePacketType;
int receivePacketSeqNum;
packet recvpckt(0, 0, 0, (char*)buffer);
recvpckt.deserialize((char*)receivePayload);
receivePacketSeqNum = recvpckt.getSeqNum();
receivePacketType = recvpckt.getType();
recvpckt.printContents();
if (receivePacketType == 2)
{
break;
}
base = receivePacketSeqNum + 1;
printf("%d\n", base);
if (base == nextSeqNum)
{
alarm(0);
}
else
{
alarm(0);
alarm(TIMEOUT_SECS);
}
if (nextSeqNum == totalPackets - 1)
{
nextSeqNum++;
int sendPacket = 0;
bzero(sendPayload, 1024);
packet * sendpckt = packetArray[nextSeqNum - 1];
sendpckt->serialize(sendPayload);
sendpckt->printContents();
sendPacket = sendto(sendSocket, sendPayload, sizeof(sendPayload), 0, (struct sockaddr *)&sendSocketStruct, sendSocketLen);
}
if (base <= totalPackets)
{
sendFlag = 1;
previousState = currentState;
currentState = wait;
}
else
{
continue;
}
}
}
else
{
break;
}
}
//Close shop.
close(receiveSocket);
close(sendSocket);
return 0;
}
The location where I suspect the loop to start is in the receiveData state.

Fixed it:
else if (currentState == receiveData)
{
receive = 0;
bzero(receivePayload, 1024);
receive = (recvfrom(receiveSocket, receivePayload, sizeof(receivePayload), 0, (struct sockaddr *)&receiveSocketStruct, &receiveSocketLen));
if (receive < 0)
{
printf("timeout");
if (tries > MAXTRIES)
{
alarm(0);
break;
printf("recvfrom() failed.");
}
previousState = currentState;
currentState = timeout;
}

Related

C++ Socket API "Heartbeat"

I'm trying to make a simple heartbeat check from client to server and vice-versa, if connection on either is broken off unexpectedly it prints a message and calls closesocket.
I spent 8 hours on this and it still isn't acceptable to my mentor. Right now I got something that works, but if breakpoint is placed before while loop and connected client is forcefully closed, trying to go past breakpoint causes crash when it should break the loop and write out error.
Server side code:
int main(int argc, char *argv[])
{
SOCKET s, sa;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
srv_address.sin_port = htons(1099);
bind(s, (sockaddr*) &srv_address, sizeof(srv_address));
int l = listen(s, 10);
if (l < 0)
printf("Listen error\n");
else
{
printf("Listen OK. Listening on port %u\n",
htons(srv_address.sin_port));
sa = accept(s, NULL, NULL);
while (true)
{
char buffer[1000];
int nRecvLen = recv(sa, buffer, 999, 0);
buffer[nRecvLen] = '\0';
int r = recv(sa, NULL, 0, 0);
if (r == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)
{
printf("Konekcija je naglo prekinuta!\n");
break;
}
else
{
if (nRecvLen > 0)
{
for (int i = 0; i < nRecvLen; i++)
{
cout << buffer[i];
}
}
}
}
closesocket(sa);
closesocket(s);
}
WSACleanup();
return 0;
}
and client side:
int main()
{
SOCKET s;
WSAData oWSAData;
WORD wVersion = 0x0001;
WSAStartup(wVersion, &oWSAData);
s = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in srv_address;
memset(&srv_address, 0, sizeof(srv_address));
srv_address.sin_family = AF_INET;
srv_address.sin_addr.S_un.S_un_b.s_b1 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b2 = xxx;
srv_address.sin_addr.S_un.S_un_b.s_b3 = x;
srv_address.sin_addr.S_un.S_un_b.s_b4 = xxx;
srv_address.sin_port = htons(1099);
int c = connect(s, (sockaddr*) &srv_address, sizeof(srv_address));
if (c < 0)
{
printf("Connection error\n");
cout << (WSAGetLastError());
}
else
{
string l = "Heartbeat\n";
int p = l.size();
char buff[1000];
strcpy_s(buff, l.c_str());
printf("Connected\n");
while (true)
{
if (send(s, buff, p, 0) > 0)
{
Sleep(1000);
}
else
{
printf("Konekcija je naglo prekinuta\n");
shutdown(s, SD_BOTH);
closesocket(s);
break;
}
}
WSACleanup();
return 0;
}
}

Multi threaded HTTP server socket hangs with CLOSE_WAIT

I have a C++ server application. The server application is acting as a HTTP
server in this case. With the large number of requests socket move to the
CLOSE_WAIT state.With small number of requests its working fine.
void *task1(void *);
static int connFd;
int noThread = 0;
int main()
{
int pId, portNo, listenFd;
socklen_t len; //store size of the address
bool loop = false;
struct sockaddr_in svrAdd, clntAdd;
pthread_t threadA[500];
portNo = 9898 ;
cout<<"td::string::npos = "<<std::string::npos<<endl;
if((portNo > 65535) || (portNo < 2000))
{
cout<<"Please enter a port number between 2000 - 65535";
return 0;
}
//create socket
listenFd = socket(AF_INET, SOCK_STREAM, 0);
if(listenFd < 0)
{
cout<< "Cannot open socket"<<endl;
return 0;
}
bzero((char*) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;
svrAdd.sin_addr.s_addr = INADDR_ANY;
svrAdd.sin_port = htons(portNo);
//bind socket
if(bind(listenFd, (struct sockaddr *)&svrAdd, sizeof(svrAdd)) < 0)
{
cout<<"Cannot bind"<<endl;;
return 0;
}
listen(listenFd, 5);
len = sizeof(clntAdd);
while (noThread < 500)
{
cout<<"Listening"<<endl;
//this is where client connects. svr will hang in this mode until client conn
connFd = accept(listenFd, (struct sockaddr *)&clntAdd, &len);
if (connFd < 0)
{
cout<<"Cannot accept connection"<<endl;
return 0;
}
else
{
cout<<"Connection successful" <<endl;
}
//pthread_create(&threadA[noThread], NULL, test::task1, NULL);
//thr_create(&threadA[noThread], NULL, task1, NULL);
pthread_create(&threadA[noThread], NULL, task1, NULL);
noThread++;
cout<<"Number of noThread :"<< noThread;
}
for(int i = 0; i < 500; i++)
{
pthread_join(threadA[i], NULL);
//thr_join(threadA[i], NULL);
cout<<"inside join"<<i;
}
}
void *task1 (void *dummyPt)
{
cout<<"Thread No: " << pthread_self();
char test[1000];
bzero(test, 1001);
bool loop = false;
int t=0;
while(t==0)
{
bzero(test, 1001);
read(connFd, test, 1001);
string t1(test);
if(tester.find("connection_request")!=std::string::npos){
if(connFd)
{
cout<<"T1 :"<<t1<<endl;
send(connFd, "HTTP/1.0 200 OK\n\n", 17, 0);
write(connFd,"Test Response",13);
}
else
cout << "Problem With collection FD";
t=1;
}
}
cout<<"Closing thread and conn"<<endl;
close(connFd);
noThread--;
return NULL;
}

Shared memory is working only the first time [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am using shared memory to pass values between processes. It's working the first time, but when I try changing it again, the value is not getting reflected in other processes. First process A changes the value and signal B. It uses it and passes back the control to A. Then A again changes the value, but this new value is not getting reflected in process B.
// FILE 1
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<iostream>
#include<netinet/in.h>
#include<sys/select.h>
#include<sys/shm.h>
#include<signal.h>
using namespace std;
struct shm
{
int aid;
int sid;
int bid;
int cid;
int portno;
int pno;
//int ports[4];
}*val;
int ports[4];
int sfds[4];
int count = 4;
void func1(int a)
{
fd_set rfds;
while (1)
{
FD_ZERO(&rfds);
struct timeval timer;
timer.tv_sec = 0;
timer.tv_usec = 10;
for (int i = 0; i < count; i++)
{
FD_SET(sfds[i], &rfds);
}
if (select(sfds[count - 1] + 1, &rfds, NULL, NULL, &timer))
{
for (int i = 0; i < count; i++)
{
if (FD_ISSET(sfds[i], &rfds))
{
val->pno = i;
val->portno = ports[i];
cout << "port number:" << val->portno << endl;
close(sfds[i]);
// Remove the corresponding sfd
for (int j = i; j < count - 1; j++)
{
sfds[j] = sfds[j + 1];
ports[j] = ports[j + 1];
}
count--;
kill(val->aid, SIGUSR2);
if (count > 0)
signal(SIGUSR1, &func1);
else
exit(1);
return;
}
}
}
}
}
void func2(int b)
{
struct sockaddr_in cliaddr;
socklen_t clilen;
int lc = 0;
for (int i = 0; i < 1; i++)
{
int nsfd = accept(sfds[val->pno], (struct sockaddr*) &cliaddr, &clilen);
if (nsfd < 0)
{
perror("Error");
exit(1);
}
cout << "Connection accepted";
send(nsfd, "OkaA", 5, 0);
close(nsfd);
}
if (close(sfds[val->pno]) < 0)
{
perror("Error closing");
exit(1);
}
cout << "Closed" << endl;
// Remove the corresponding sfd
for (int i = val->pno; i < count - 1; i++)
{
sfds[i] = sfds[i + 1];
ports[i] = ports[i + 1];
}
count--;
cout << " val->portnumber " << val->portno << endl;
kill(val->bid, SIGUSR1);
if (count > 0)
signal(SIGUSR2, &func2);
else
exit(1);
return;
}
int main()
{
int shmid = shmget(123456, sizeof(struct shm), IPC_CREAT | 0666);
if (shmid < 0)
{
perror("Error");
}
val = (struct shm*) shmat(shmid, NULL, 0);
//cout<<"yo2";
signal(SIGUSR1, &func1);
signal(SIGUSR2, &func2);
for (int i = 0; i < 4; i++)
{
//val->ports[i] = 7590+i;
sfds[i] = socket(AF_INET, SOCK_STREAM, 0);
const int optVal = 1;
const socklen_t optLen = sizeof(optVal);
int rtn = setsockopt(sfds[i], SOL_SOCKET, SO_REUSEADDR, (void*) &optVal,
optLen);
if (rtn < 0)
{
perror("Error");
exit(1);
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(7590 + i);
ports[i] = i;
servaddr.sin_addr.s_addr = INADDR_ANY;
if (bind(sfds[i], (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0)
{
perror("Error");
exit(1);
}
if (listen(sfds[i], 1) < 0)
{
perror("Error");
exit(1);
}
}
int c = fork();
if (c > 0)
{
val->aid = c;
val->sid = getpid();
kill(getpid(), SIGUSR1);
while (1)
;
}
else if (c == 0)
{
while (1)
;
}
else
{
perror("Error");
exit(1);
}
}
// FILE 2
#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<iostream>
#include<netinet/in.h>
#include<sys/select.h>
#include<sys/shm.h>
using namespace std;
struct shm
{
int aid;
int sid;
int bid;
int cid;
int pno;
int portno;
}*val;
int sfds[4];
int count = 4;
void func1(int a)
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(7590 + val->portno);
servaddr.sin_addr.s_addr = INADDR_ANY;
const int optVal = 1;
const socklen_t optLen = sizeof(optVal);
cout << val->portno << " vpn " << endl;
int rtn = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*) &optVal,
optLen);
while (bind(sfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0)
{
perror("Error");
}
cout << endl << "Done" << endl;
if (listen(sfd, 1) < 0)
{
perror("Error");
exit(1);
}
for (int i = 0; i < 1; i++)
{
struct sockaddr_in cliaddr;
socklen_t clilen;
int nsfd = accept(sfd, (struct sockaddr*) &cliaddr, &clilen);
send(nsfd, "OkaB", 5, 0);
}
close(sfd);
signal(SIGUSR1, &func1);
kill(val->cid, SIGUSR1);
}
int main()
{
signal(SIGUSR1, &func1);
int shmid = shmget(123456, sizeof(struct shm), IPC_CREAT | 0666);
if (shmid < 0)
{
perror("Error");
}
val = (struct shm*) shmat(shmid, NULL, 0);
val->bid = getpid();
while (1)
;
}
The problem may come from the struct shm definition:
In file 1
struct shm
{
int aid;
int sid;
int bid;
int cid;
int portno;
int pno;
//int ports[4];
}*val;
In other file :
struct shm
{
int aid;
int sid;
int bid;
int cid;
int pno;
int portno;
}*val;
pno and portno are not at the same place.
And as LPs pointed, only one process should create the shared memory (IPC_CREAT)

poll() socket programming tcp linux multiple connections issue

I'm new to socket programming, but I have followed ibm example at https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzab6/poll.htm and changed some code to make it better but when I connect to the server via telnet ip port, and make it echo messages it works for the first client that connects but on second it does not echo the messages?
#include <netinet/in.h> // sockaddr_in struct
#include <arpa/inet.h> //inet_addr()
#include <sys/socket.h>
#include <errno.h> //errors
#include <stdio.h> //perror()
#include <cstdlib> //EXIT_FAILURE
#include <sys/ioctl.h> //FIONBIO
#include <unistd.h> //close file descriptor
#include <fcntl.h> //make non blocking
#include <poll.h> //poll stuff
#include <string.h> //memset
int main()
{
int s = -1;
int rc;
int optval = 1;
int timeout;
bool end_server = false; //because we need to log if EWOULDBLOCK is true...
struct pollfd fds[200]; //initialize pollfd struct
int nfds = 1; // nfds_t really set to 1 else it will be 199 once we pass it to poll....
int current_size = 0;
int new_s = -1;
int close_conn;
char *buff;
int len;
bool compress_array;
s = socket(AF_INET, SOCK_STREAM, 0);
//make socket description reusable with SO_REUSEADDR
rc = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&optval), sizeof(optval));
if(rc < 0){
perror("setsockopt()");
close(s);
exit(EXIT_FAILURE);
}
//make socket non-blocking
//rc = ioctl(s, FIONBIO, reinterpret_cast<char*>(&optval));
//if(rc < 0)
//{
// perror("ioctl()");
// close(s);
// exit(EXIT_FAILURE);
//}
fcntl(s, F_SETFL, O_NONBLOCK);
struct sockaddr_in saddr;
//initialize sockaddr_in struct
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(80);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
rc = bind(s, reinterpret_cast<struct sockaddr *>(&saddr), sizeof(saddr));
if(rc < 0){
perror("bind()");
exit(EXIT_FAILURE);
}
rc = listen(s, 32);
if(rc < 0){
perror("listen() failed");
close(s);
exit(EXIT_FAILURE);
}
//initialize fds struct
memset(&fds, 0, sizeof(fds));
fds[0].fd = s;
fds[0].events = POLLIN; //check if data to read
//initialize timeout value to 3 mins based on millisecs
//timeout = (3 * 60 * 1000); // because function will be like sleep() that uses millisecs
timeout = 10000;
do{
//call poll() and wait 3 mins to complete because of timeout
printf("Waiting on poll()...\n");
rc = poll(fds, nfds, timeout);
if(rc < 0){
perror("poll() failed");
exit(EXIT_FAILURE);
}
//check if 3 minutes timeout expired
if(rc == 0){
printf("poll() timed out ending program...\n");
exit(EXIT_FAILURE);
}
current_size = nfds;
for(int i = 0; i < current_size; i++)
{
//loop thru fds and check if revents returns POLLIN, means the fd have data to read...
if(fds[i].revents == 0)
continue;
//if revents is not POLLIN then exit program and log
if(fds[i].revents != POLLIN){
printf("revents != POLLIN, revents = %d\n", fds[i].revents);
//end_server = true;
//break;
//perror("revents unknown");
//exit(EXIT_FAILURE);
close(fds[i].fd);
fds[i].fd = -1;
break;
}
if(fds[i].fd == s){
printf("Listening socket available\n");
do{
//accept each new incoming connections
new_s = accept(s, NULL, NULL);
if(new_s < 0){
if(errno != EWOULDBLOCK){
perror("accept() failed because of socket would block");
end_server = true;
}
//printf("something else wrong with accept()\n");
break;
}
//add new incoming connection
printf("new incoming connection - nfds: %d\n", new_s);
fds[nfds].fd = new_s;
fds[nfds].events = POLLIN;
nfds++;
//continue;
//loop back up and accept another connection
} while(new_s != -1);
}
// file descriptor is readable because its now new_s instead of s
else {
printf("descriptor %d is readable\n", fds[i].fd);
close_conn = false;
//receive all data on this connection till we go back and poll again
do {
rc = recv(fds[i].fd, reinterpret_cast<void*>(&buff), sizeof(buff), 0);
if(rc < 0){
if(errno != EWOULDBLOCK){
perror("recv() failed");
close_conn = true;
}
break;
}
//check if conn was closed by client
if(rc == 0){
printf("connection closed");
close_conn = true;
break;
}
//data was received
len = rc;
printf("%d bytes received", len);
//process stuff or echo data back to client
rc = send(fds[i].fd, reinterpret_cast<void*>(&buff), sizeof(buff), 0);
if(rc < 0){
perror("send() failed");
close_conn = true;
break;
}
memset(&buff, 0, sizeof(buff));
} while (true);
if(close_conn){
close(fds[i].fd);
fds[i].fd = -1;
compress_array = true;
}
}
}
if(compress_array){
compress_array = false;
int i = 0;
for(i = 0; i < nfds; i++){
if(fds[i].fd == -1){
for(int j = i; j < nfds; j++){
fds[j].fd = fds[j+1].fd;
}
i--;
nfds--;
}
}
}
} while (end_server == false);
//clean all sockets that are open
for(int i = 0; i < nfds; i++){
if(fds[i].fd > 0){ // if already -1 don't need to close socket
close(fds[i].fd);
fds[i].fd = -1;
}
}
return 0;
}
Ahh it was because I looped with while(true) so it kept looping trying to recv data instead of going back up and add new connection to the list.

Sockets over NDK

When I'm connecting with a socket in NDK, as a result of the read call, I always get -1.(Error).
I was looking over the internet several times and I couldn't find a solution. Can you help me?
Here is my code.
void * SocketManager::socketCall(void *ptr) {
int socket_, n;
SocketManager *manager = (SocketManager*) ptr;
while (manager->semaph) ;
manager->semaph = true;
bool didConnect = false;
size_t bufferSize = 32000;
char buffer[bufferSize];
const char* value = manager->host.c_str();
stringstream strValue;
strValue << value;
unsigned int host;
strValue >> host;
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(10983);
inet_aton(manager->host.c_str(), &server_address.sin_addr);
socket_ = socket(AF_INET, SOCK_STREAM, 0);
if (socket_ < 0)
CCLog("ERROR ABRIENDO EL SOCKET");
n = ::connect(socket_, (struct sockaddr *) &server_address,sizeof(server_address));
if (n < 0)
close(socket_);
manager->onConnect();
didConnect = true;
while (!manager->mustDisconnect) {
n = read(socket_, &buffer, bufferSize);
if(n<=0)
break;
manager->onReadData(buffer, sizeof(buffer));
}
if (socket_) {
close(socket_);
if (didConnect)
manager->onDisconnect();
else
manager->onTimeout();
}
manager->semaph = false;
manager->mustDisconnect = false;
return 0;
}