socket poll programing

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/socket.h>

#include <poll.h>

#include <sys/time.h>

#include <netinet/in.h>

#include <errno.h>

#include <unistd.h>

 

#define PORT 6002

 

//最多处理的connect

#define BACKLOG 5

 

//当前的连接数

int currentClient = 0;

 

//数据接受 buf

#define REVLEN 10

char recvBuf[REVLEN];

 

#define OPEN_MAX 1024

 

 

struct pollfd* _fd_init(struct pollfd* const fd_set) 

{

struct pollfd *poll_fd_set;

if (fd_set == NULL)

{

poll_fd_set = (struct pollfd *) malloc(OPEN_MAX * sizeof(struct pollfd));

}

else 

{

poll_fd_set = fd_set;

}

return poll_fd_set;

}

 

void _fd_zero(struct pollfd* fd_set) 

{

    for(int i = 0; i < OPEN_MAX; i++)

    {

        fd_set[i].fd = -1;

    }

}

 

void _fd_set(int fd, struct pollfd* const fd_set) 

{

fd_set[0].fd = fd;

    fd_set[0].events = POLLIN; //POLLRDNORM;

}

 

 

class SocketException 

{

private:

 

int errorCode;

 

char *message;

 

public:

 

SocketException(int errorCode) 

{

this->errorCode = errorCode;

this->message = NULL;

}

 

SocketException(int errorCode, char *message) 

{

this->errorCode = errorCode;

this->message = message;

}

 

int getCode() 

{

return errorCode;

}

 

char* getMessage() 

{

return message;

}

};

 

class HardSocket 

{

private: 

 

int sfd;

 

public:

 

HardSocket() throw (SocketException)

{

/**

* On success, a file descriptor for the new socket is returned.  On 

* error, -1 is returned, and errno is set appropriately.

*/

int fd = socket(AF_INET, SOCK_STREAM, 0);

//fd = -1;

if (fd == -1)

{

int error = errno;

throw SocketException(error);

this->sfd = fd;

}

 

~HardSocket() 

{

printf("~HardSocket\n");

}

 

int getPlainSocket() 

{

return this->sfd;

}

 

void bind(int port) throw (SocketException)

{

struct sockaddr_in server_addr;

bzero(&server_addr, sizeof(server_addr));

server_addr.sin_family  =  AF_INET;

server_addr.sin_port = htons(port);

server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

 

int error = ::bind(this->sfd, (struct sockaddr*) &server_addr, sizeof(server_addr));

if(error == -1) 

{

error = errno;

throw SocketException(error);

}

}

 

void listen() throw (SocketException)

{

this->listen(50);

}

 

void listen(int backlog) throw (SocketException)

{

int error = ::listen(this->sfd, backlog);

if(error == -1) 

{

error = errno;

throw SocketException(error);

}

}

};

 

 

class Poll

{

 

};

 

 

int main()

{

HardSocket *socket = NULL;

try

{

socket = new HardSocket();

socket->bind(PORT);

socket->listen();

}

catch (SocketException e)

{

printf("socket error %d\n", e.getCode());

// 有问题, 这里实例化一个socket对象时抛出异常的话, 析构函数不会被调用以释放对象资源

//sleep(5000);

return 1;

}

 

/**

* struct pollfd {

     *     int   fd;         // file descriptor 

     *     short events;     // requested events 

     *     short revents;    // returned events 

     * };

*/

struct pollfd clientfd[OPEN_MAX];

_fd_zero(clientfd);

_fd_set(socket->getPlainSocket(), clientfd);

 

int nfds = 0;

while(1) 

{

        int timeout = 3000;

        int error = poll(clientfd, nfds+1, timeout);

 

        if(error < 0) // On error, -1 is returned, and errno is set appropriately.

        {

            printf("select error %d\n", errno);

            break;

        }

        else if(error == 0) // A value of 0 indicates that the call timed out and no file descriptors were ready.

        {

            printf("timeout ...\n");  

            continue;  

        }

 

        for(int i = 0; i <= nfds; i++)  

        {  

            if(clientfd[i].fd < 0) 

{

                continue;

}

 

if (clientfd[i].fd == socket->getPlainSocket())

{

/**

* Case indicates that one event that data to read (POLLIN or POLLRDNORM) contained.

* // The following values are defined by XPG4. 

* #define POLLRDNORM POLLIN

*/

if (clientfd[i].revents & POLLIN) 

{

printf("clientfd[%d].revents & POLLIN %d(0x%x) clientfd[%d].revents %d(0x%x), POLLIN %d(0x%x)\n", 

i, 

clientfd[i].revents & POLLIN, 

clientfd[i].revents & POLLIN, 

i, 

clientfd[i].revents, 

clientfd[i].revents, 

POLLIN, 

POLLIN);

 

int sockSvr = accept(socket->getPlainSocket(), NULL, NULL);//(struct sockaddr*)&client_addr

if(sockSvr == -1)  

{

printf("accpet error\n");  

}

else  

{

currentClient++;  

}

 

for(i=0; i<OPEN_MAX; i++)  

{

if(clientfd[i].fd<0)  

{

clientfd[i].fd = sockSvr;  

break;  

}

}

if(i == OPEN_MAX) 

{

printf("too many connects\n");  

return -1;  

}

clientfd[i].events = POLLIN;//POLLRDNORM;  

if(i > nfds) 

{

nfds = i;

}

}

            }

else if (clientfd[i].revents & (POLLIN | POLLERR)) // POLLRDNORM  

            {

printf("clientfd[%d].revents & (POLLIN | POLLERR) %d(0x%x) clientfd[%d].revents %d(0x%x), POLLIN %d(0x%x), POLLERR %d(0x%x)\n", 

i, 

clientfd[i].revents & (POLLIN | POLLERR), 

clientfd[i].revents & (POLLIN | POLLERR), 

i, 

clientfd[i].revents, 

clientfd[i].revents, 

POLLIN, 

POLLIN, 

POLLERR, 

POLLERR);

int recvLen = 0;

                if(recvLen != REVLEN)  

                {

                    while(1)  

                    {

printf("recv....\n");

                        //recv数据

                        int bytes = recv(clientfd[i].fd, (char *) recvBuf+recvLen, REVLEN - recvLen, 0);

                        if(bytes == 0) 

                        {

printf("stream socket %d peer has performed an orderly shutdown\n", clientfd[i].fd);

                            clientfd[i].fd = -1;

                            recvLen = 0;

                            break;

                        }  

                        else if(bytes == -1) 

                        {

printf("receive a message from a socket error %d\n", errno);

                            clientfd[i].fd = -1;

                            recvLen = 0;

                            break;

                        }

                        //数据接受正常  

                        recvLen = recvLen + bytes;

                        if(recvLen < REVLEN) 

                        {

                            continue;

                        }

                        else

                        {

                            //数据接受完毕  

                            printf("buf = %s\n",  recvBuf);

                            //close(client[i].fd);

                            //client[i].fd = -1;

                            recvLen = 0;

                            break;

                        }

                    }

                }

            }

        }

    }

 

    return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值