C-使用轮询在套接字和stdin之间进行多路复用-服务器 [英] C - Using poll to multiplex between socket(s) and stdin - Server

查看:125
本文介绍了C-使用轮询在套接字和stdin之间进行多路复用-服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个客户端服务器应用程序,并且正在使用poll在多个客户端套接字和stdin之间进行多路复用,在其中可以插入命令(例如:停止服务器).我相信我的代码的结构(逻辑")是正确的,但是它并没有表现出我期望的方式:

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

我已经删除了recv中的一些代码并发送以使代码更易于阅读. 它无法正常运行(它只是挂起,不接受连接或对来自stdin的输入做出反应).

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 :-).

在此先感谢您的帮助.

推荐答案

  1. 您应该设置每个pfd[i].fd = -1,以便它们最初被poll()忽略.
  2. poll(pfd, 1, 0)是错误的,至少应为poll(pfd, 2, 0)甚至是poll(pfd, NSERVER, 0).
  3. while(i<=NSERVER)应该是while(i<NSERVER)
  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)

您的程序可能会挂起,因为您循环了pfd数组,该数组未初始化并且包含.fd和.revents的随机值,因此它希望在某个可能阻塞的随机FD上发送send()或recv().在i<NSERVER循环中执行if(pdf[i].fd < 0) {i++; continue;}.

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.

您也不要在新接受的套接字上设置pfd[pos].events = POLLIN.除非您有要发送的内容,否则请勿设置POLLOUT,因为它将几乎每次触发.

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.

这篇关于C-使用轮询在套接字和stdin之间进行多路复用-服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆