Unix网络编程-poll模型echo服务器

poll函数和select函数差不多。以下是一个简单的回显服务器

#include <iostream>
using namespace std;
#include <poll.h>
#include <limits.h>

#define OPEN_MAX 64

int main()
{
    int i, maxi, listenfd, connfd, sockfd;
    int nready;
    ssize_t n;
    socklen_t clilen;
    struct pollfd client[OPEN_MAX];
    struct sockaddr_in cliaddr, servaddr;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(10002);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if(bind(listenfd, (sockaddr*)&servaddr, sizeof(servaddr)) == -1)
    {
        cout << "bind error" << endl;
        return -1;
    }

    listen(listenfd, 5);

    client[0].fd = listenfd;
    client[0].events = POLLRDNORM;
    for(int i = 1; i < OPEN_MAX; i++)
    {
        client[i].fd = -1;
    }

    maxi = 0;

    cout << "startup sucess port : " << servaddr.sin_port << endl;
    cout << "Max connect :" << OPEN_MAX << endl;

    for(;;)
    {
        nready = poll(client, maxi + 1, -1);
        if(nready == -1)
        {
            cout << "poll error" << endl;
        }

        if(client[0].revents & POLLRDNORM)//new client connection
        {
            clilen = sizeof(cliaddr);
            connfd = accept(listenfd, (sockaddr*)&cliaddr, &clilen);

            for(i = 1; i < OPEN_MAX; i++)
            {
                if(client[i].fd < 0)
                {
                    client[i].fd = connfd; //save des
                    break;
                }
            }

            if(i == OPEN_MAX)
            {
                cout << "too many clients" << endl;
                return -1;
            }

            client[i].events = POLLRDNORM;
            if(i > maxi)
            {
                maxi = i;
            }

            if(--nready <= 0)
            {
                continue;
            }
        }

        for(i = 1; i <= maxi; i++)
        {
            if((sockfd = client[i].fd) < 0)
            {
                continue;
            }

            if(client[i].revents & (POLLRDNORM | POLLERR))
            {
                char buffer[1024] = {0};
                if((n = recv(sockfd, buffer, 1024, 0)) < 0)
                {
                    if(errno == ECONNRESET)
                    {
                        //connection reset by client
                        close(sockfd);
                        client[i].fd = -1;
                    }
                    else
                    {
                        cout << "read error" << endl;
                    }
                }
                else if(n == 0)
                {
                    //connect close by client
                    close(sockfd);
                    client[i].fd = -1;
                }
                else
                {
                    send(sockfd, buffer, 1024, 0);
                }

                if(--nready <= 0)
                {
                    break;
                }
            }
        }

    }

    return 0;
}
时间: 2024-08-01 05:01:43

Unix网络编程-poll模型echo服务器的相关文章

UNIX网络编程-Poll模型学习

1.相关接口介绍 1.1 poll ---------------------------------------------------------------------- #include <poll.h> int poll(struct pollfd *fdarray, unsigned long nfds, int timeout); 返回:准备好描述字的个数,0—超时,-1—出错. --------------------------------------------------

unix网络编程各种TCP客户-服务器程序设计实例附环境搭建和编译方法(一)

一,到http://download.csdn.net/detail/ts173383201/4505201去下载源代码,然后解压: 二,cd到你解压后的文件夹下,就是有configure的那个目录下,执行命令./configure: 三,执行cd lib跳到lib目录下,执行make命令,会在上层目录(就是刚才有configure那个目录)生成libunp.a文件 四,复制这个静态库libunp.a到/usr/lib/和/usr/lib64/中; 五,接下来在目录中找到unp.h和config

UNIX网络编程入门——TCP客户/服务器程序详解

前言 最近刚开始看APUE和UNP来学习socket套接字编程,因为网络这方面我还没接触过,要等到下学期才上计算机网络这门课,所以我就找了本教材啃了一两天,也算是入了个门. 至于APUE和UNP这两本书,书是好书,网上也说这书是给进入unix网络编程领域初学者的圣经,这个不可置否,但这个初学者,我认为指的是接受过完整计算机本科教育的研究生初学者,需要具有完整计算机系统,体系结构,网络基础知识.基础没打好就上来啃书反而会适得其反,不过对于我来说也没什么关系,因为基础课也都上得差不多了,而且如果书读

《UNIX网络编程》入门客户端服务器例子

最近在看<UNIX网络编程>(简称unp)和<Linux程序设计>,对于unp中第一个获取服务器时间的例子,实践起来总是有点头痛的,因为作者将声明全部包含在了unp.h里,导致后面编写代码会对这个头文件造成依赖,而学习不到调用了相应功能之后,应该包含哪些确切的头文件. 再者,我下载了unp.h之后,头文件包含再次产生了其他的依赖缺失,因此便参考了<Linux程序设计>中socket一章的入门例子的头文件包含,并且编译中仍然找不到的包含或者是宏定义在unp.h中搜索并粘贴

【UNIX网络编程】TCP客户/服务器程序示例

做一个简单的回射服务器: 客户从标准输入读入一行文本,写给服务器 -> 服务器从网络输入读入这行文本,并回射给客户 -> 客户从网络输入读入这行回射文本,并显示在标准输出上 以下是我的代码(部分.h文件是由unpv13e文件夹中的.c文件改名得到) #include "../unpv13e/unp.h" #include "../unpv13e/apueerror.h" #include "../unpv13e/wrapsock.h"

UNIX网络编程-Select模型学习

1.相关接口介绍 1.1 select ---------------------------------------------------------------------- #include <sys/select.h> #include <sys/time.h> int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeou

unix网络编程各种TCP客户-服务器程序设计实例(三)

第五种  TCP预先派生子进程服务器程序: 对预先派生子进程服务器的最后一种改动就是由父进程调用accept,然后再将所接受的已连接描述字传递给子进程.父进程必须跟踪子进程的忙闲状态,以便给空闲子进程传递新的描述字.为每个子进程维护一个信息结构,用来管理各子进程. 在调用fork之前,先创建一个字节流管道(Unix域的字节流套接口),它是Unix域的字节流套接口.当子进程派生后,父进程关闭一个描述字(sockfd[1]),子进程关闭另一个描述字(sockfd[0]),此外,子进程将流管道的字节所

unix网络编程各种TCP客户-服务器程序设计实例(二)

本节我们接着介绍另外的几种TCP客户-服务器程序: 第四种:TCP并发服务器,每个客户一个子线程 在我们前面的并发服务器程序例子中可以看出:父进程接受连接,派生子进程,子进程处理与客户的交互. 这种模式的问题: fork()是昂贵的.内存映像要从父进程拷贝到子进程,所有描述字要在子进程中复制等等. fork()子进程后,需要用进程间通信在父子进程之间传递信息. 一个进程中的所有线程共享相同的全局内存,这使得线程很容易共享信息,但是这种简易型也带来了同步问题.一个进程中的所有线程不仅共享全局变量,

《UNIX网络编程》TCP客户端服务器:并发、消息回显

经过小小改动,把前面基础的例子做出一点修改. 并发服务器,服务器每accept一个请求就fork()一个新的子进程. 编译运行方法同前一篇. /*client_tcp.c*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #incl