Ç - 使用轮询插座(S)和标准输入之间的复用 - 服务器(C - Using poll to mu

2019-10-17 12:12发布

我正在写一个客户端服务器应用程序,我使用轮询多个客户插座和标准输入,在那里我可以插入命令(例如:停止服务器)之间的复用。 我相信我的代码的结构(“逻辑”)是正确的,但它不是表现我希望它的方式:

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++;
    }
}

我已经删除了的recv里面的一些代码,并发送,使代码更易于阅读。 它未能表现(它只是挂起,不接受连接或从标准输入反应输入)。

注意:我宁愿使用poll在选择,所以请不要点选择:-)。

感谢您的任何援助。

Answer 1:

  1. 你应该设置每一个pfd[i].fd = -1 ,所以他们得到的调查最初忽略()。
  2. poll(pfd, 1, 0)是错误的,应当至少是poll(pfd, 2, 0)或甚至poll(pfd, NSERVER, 0)
  3. while(i<=NSERVER)应当是while(i<NSERVER)

你的程序可能挂起,因为你通过PFD数组,没有初始化,containes为.FD和.revents随机值,所以想要发送()或recv()上可能会阻止一些随机的FD循环。 做if(pdf[i].fd < 0) {i++; continue;} if(pdf[i].fd < 0) {i++; continue;}i<NSERVER循环。

您还没有设置pfd[pos].events = POLLIN在新接受的套接字。 不要设置POLLOUT ,除非你有东西送,因为它几乎每一次触发。



文章来源: C - Using poll to multiplex between socket(s) and stdin - Server