C - Using poll to multiplex between socket(s) and stdin - Server

删除回忆录丶 提交于 2020-01-05 07:30:10

问题


I'm writing a client server application and I'm using poll to multiplex between several client sockets and stdin, where I can insert commands (example: stop the server). I believe the structure (the "logic") of my code is correct, however it's not behaving the way I expect it to:

struct pollfd pfd[NSERVER]; //defined as 10
pfd[0].fd = fileno(stdin);
pfd[0].events = POLLIN;
pfd[1].fd = socktfd; //server bind, listen socket
pfd[1].events = POLLIN;
struct sockaddr_storage remoteaddr; // client address
socklen_t addrlen;
char remoteIP[INET6_ADDRSTRLEN];
addrlen = sizeof remoteaddr;
char buf[1024];     // buffer
int pos=2;  

while(poll(pfd,1,0) >= 0)
{
    if(pfd[0].revents & POLLIN) { //stdin
            //process input and perform command
        }
    if(pfd[1].revents & POLLIN) {
        /* new connection */
        int connsockfd = accept(socktfd, (struct sockaddr *)&remoteaddr,&addrlen);  
        pfd[pos].fd=connsockfd;
    }
    int i=2;
    //Loop through the fd in pfd for events
    while (i<=NSERVER)
    {
        if (pfd[i].revents & POLLIN) {
            int c=recv(pfd[i].fd, buf, sizeof buf, 0);
            if(c<=0) {
                if (c==0)
                {
                /* Client closed socket */
                    close(pfd[i].fd);
                }
            }else
            {//Client sent some data
                c=send(pfd[i].fd,sbuff,z,0);
                if (c<=0)
                {
                    Error;
                }
            free(sbuff);
            }
        }
        i++;
    }
}

I've removed some code inside the recv and send to make the code easier to read. It fails to behave (it just hangs, doesn't accept connections or reacts to input from stdin).

Note: I would prefer to use poll over select, so please don't point to select :-).

Thanks in advance for any assistance.


回答1:


  1. you should set every pfd[i].fd = -1, so they get ignored initially by poll().
  2. poll(pfd, 1, 0) is wrong and should at least be poll(pfd, 2, 0) or even poll(pfd, NSERVER, 0).
  3. while(i<=NSERVER) should be while(i<NSERVER)

Your program probably hangs, because you loop through the pfd array, which is not initialized and containes random values for .fd and .revents, so it wants to send() or recv() on some random FD which might block. Do if(pdf[i].fd < 0) {i++; continue;} in the i<NSERVER loop.

You also don't set pfd[pos].events = POLLIN on newly accepted sockets. Don't set POLLOUT unless you have something to send, because it will trigger almost every time.



来源:https://stackoverflow.com/questions/13900984/c-using-poll-to-multiplex-between-sockets-and-stdin-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!