I am writing a tcp server interface in C. In this interface, I would require to listen for command and send periodic outputs through the same sockets. I would think in this case I would need to program my sockets to be non-blocking. Here is my code
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
int setNonblocking(int fd)
{
int flags;
#if defined(O_NONBLOCK)
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
flags = 1;
return ioctl(fd, FIOBIO, &flags);
#endif
}
int main()
{
int lsock;
struct sockaddr_in saddr;
short int port;
char buffer[MAX_DATA];
int socketOption=1;
int LISTENQ =1;
/// creating sockets
if ( (lsock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
{
printf(" Error: sockets creation \n");
return -1;
}
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(2222);
setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, &socketOption, sizeof(socketOption));
setNonblocking(lsock);
if ( bind(lsock, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)) < 0 )
{
fprintf(stderr, "ECHOSERV: Error calling bind()\n");
return -1;
}
if ( listen(lsock, LISTENQ) < 0 )
{
fprintf(stderr, "ECHOSERV: Error calling listen()\n");
return -1;
}
bool running = true;
bool bConnected = true;
while ( running )
{
int csock;
time_t start = time(NULL);
time_t now;
if ( (csock = accept(lsock, NULL, NULL) ) < 0 )
{
int errno_s = errno;
printf("The error is %d \n", errno_s);
fprintf(stderr, "ECHOSERV: Error calling accept()\n");
return -1;
}
else
{
bConnected =true;
}
while(bConnected)
{
int n;
if((n=recv(lsock, buffer, MAX_DATA, 0)) > 0)
{
printf("Command Handling \n");
}
if(now - start == 100)
{
printf("Data Sending \n");
}
}
return 0;
}
The program always run into error whenever accept() is being called, I wonder why csock always return -1? I then tried to print out the errno. The errno read 11, which seems to be EAGAIN ( telling to try again ). So should I ignore this error?
I did think about other method to achieve what I want eg using select() and a set of file sockets... but somehow i think it might run into problem
Need your opinion and help on this
REgards
CodePudding user response:
See the accept man page:
If no pending connections are present on the queue, and the socket is not marked as nonblocking,
accept()
blocks the caller until a connection is present. If the socket is marked nonblocking and no pending connections are present on the queue,accept()
fails with the errorEAGAIN
orEWOULDBLOCK
.
You can use select()
to test for data on a listening socket, and then call accept()
only when it actually has data, ie a pending connection.