I'm connected to certain client then we're communicating. Another client connects to my server which will instantly output that there's a new connection.. eg Accepting while listening to other clients?.. How can i do that?..
I have already a working one but it only does one thing at a time. When i'm already communicating with my client i can't accept incoming connection or data to other clients. I can only accept new connection or data from other clients when the client i'm communicating is disconnected. how can i do so that it can process both accept and listen to client at the same time. I don't want to use threads.
Here's a part of my code.
do
{
fduse = fdin;
printf("Waiting for Connection\n");
err = select(sMax + 1, &fduse, NULL, NULL, NULL);
if (err < 0)
{
perror(" select() failed");
break;
}
DescRead = err;
for (SockStorage = 0; SockStorage <= sMax && DescRead > 0; ++SockStorage)
{
if (FD_ISSET(SockStorage, &fduse))
{
DescRead -= 1;
if (SockStorage == socketFd)
{
printf(" Listening socket is readable\n");
do
{
NewSFD =
accept(socketFd, (struct sockaddr *)&cli_addr, &clilen);
if (NewSFD < 0)
{
if (errno != EWOULDBLOCK)
{
perror(" accept() failed");
DCSERVER = TRUE;
}
break;
}
if (ClientCount < MAX_CLIENTS)
{
for (loop = 0; loop < MAX_CLIENTS; loop++)
{
if (Clients[loop].connected_sock < 0)
{
Clients[loop].connected_sock = NewSFD;
break;
}
}
ClientCount++;
}
else
{
printf("Maximum Client Reached.\n");
char *sendtoclient = "Server full. ";
send(NewSFD, sendtoclient, strlen(sendtoclient), 0);
close(NewSFD);
break;
}
ip = ntohl(cli_addr.sin_addr.s_addr);
printf(" Connection from %d.%d.%d.%d\n",
(int)(ip >> 24) & 0xff,
(int)(ip >> 16) & 0xff,
(int)(ip >> 8) & 0xff, (int)(ip >> 0) & 0xff);
dlogs(ip);
FD_SET(NewSFD, &fdin);
if (NewSFD > sMax)
sMax = NewSFD;
}
while (NewSFD != -1);
}
else
{
int d;
for (d = 0; d < MAX_CLIENTS; d++)
{
printf("Descriptor ID: %d\n", Clients[d].connected_sock);
}
pfds[0].fd = fd;
pfds[0].events = POLLIN;
pfds[1].fd = SockStorage;
pfds[1].events = POLLIN;
state = FALSE;
do
{
rc = poll(pfds, 2, -1);
if (pfds[0].revents & POLLIN)
{
while ((nbytes = read(fd, buf, sizeof (buf) - 1)) > 0)
{
buf[nbytes] = '\0';
printf("%s\n", buf);
}
pfds[0].events = 0;
pfds[1].events = POLLIN | POLLOUT;
}
if (pfds[1].revents & POLLIN)
{
err = recv(SockStorage, strbuf, sizeof (strbuf), 0);
if (err < 0)
{
if (errno != EWOULDBLOCK)
{
perror(" recv() failed");
state = TRUE;
}
break;
}
if (err == 0)
{
printf(" Connection closed\n");
state = TRUE;
break;
}
dSize = err;
printf(" %d bytes received\n", dSize);
}
if (pfds[1].revents & POLLOUT)
{
int s;
for (s = 0; s < MAX_CLIENTS; s++)
{
if (Clients[s].connected_sock > 0)
{
err =
send(Clients[s].connected_sock, buf,
strlen(buf), 0);
if (err < 0)
{
perror(" send() failed");
track = s;
state = TRUE;
break;
}
}
}
pfds[0].events = POLLIN;
pfds[1].events = POLLIN;
}
}
while (TRUE);
fopen("/sockF.txt", "w");
if (state)
{
ClientCount--;
close(SockStorage);
FD_CLR(SockStorage, &fdin);
if (SockStorage == sMax)
{
while (FD_ISSET(sMax, &fdin) == FALSE)
sMax -= 1;
}
}
}
}
}
} while (DCSERVER == FALSE);
cleanUP(SockStorage, sMax);
}
I've been working on it for two days and still i can't get it. thanks..
Well, to give you an example of a working multi-connection daemon, have a look at this example
If you need a further explanation to go with it, shoot.
Note, the code in that example has been stripped of things like daemon_init()
, etc, so just copy-pasting blindly and trying to compile it won't work.
Added setnonblocking()
as per request.
void setnonblocking(sock)
int sock;
{
int opts;
opts = fcntl(sock, F_GETFL);
if (opts < 0)
{
syslog(LOG_ERR, "fcntl(F_GETFL) failed");
exit(EXIT_FAILURE);
}
opts = (opts | O_NONBLOCK);
if (fcntl(sock, F_SETFL, opts) < 0)
{
syslog(LOG_ERR, "fcntl(F_SETFL) failed");
exit(EXIT_FAILURE);
}
return;
}
And daemon_init()
int daemon_init(void)
{
pid_t pid;
int i;
if ((pid = fork()) < 0)
{
return -1;
}
else if (pid != 0)
{
exit(0);
}
for (i=getdtablesize();i>=0;--i) close(i);
i = open("/dev/null", O_RDWR); /* open stdin */
dup(i); /* stdout */
dup(i); /* stderr */
setsid();
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.