免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2318 | 回复: 4
打印 上一主题 下一主题

[C++] 这段代码,总觉得哪点不对劲. [复制链接]

论坛徽章:
11
2015年迎新春徽章
日期:2015-03-04 09:55:282017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之辽宁
日期:2016-12-15 10:24:1715-16赛季CBA联赛之佛山
日期:2016-11-30 09:04:2015-16赛季CBA联赛之江苏
日期:2016-04-29 15:56:1215-16赛季CBA联赛之同曦
日期:2016-04-12 13:21:182016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之山东
日期:2016-02-16 11:37:52每日论坛发贴之星
日期:2016-02-07 06:20:00程序设计版块每日发帖之星
日期:2016-02-07 06:20:0015-16赛季CBA联赛之新疆
日期:2018-01-09 16:25:37
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-09-02 13:04 |只看该作者 |倒序浏览
[ 本帖最后由 bskay 于 2015-09-02 13:07 编辑 ]

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <list>
#include <cassert>

#include <time.h>

#include <infiniband/verbs.h>

//strerror
#include <string.h>
#include <stdlib.h>

#include <poll.h>

#include <sys/shm.h>

#include <sys/wait.h>
#include <sys/epoll.h>

#include <sys/socket.h>
#include <sys/time.h>

#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#ifdef _DEBUG
#undef _DEBUG
#define _DEBUG(fmt,arg...) {fprintf(stdout, fmt, ##arg);fflush(stdout);}
#define _ERROR(fmt,arg...) {fprintf(stderr, fmt, ##arg);fflush(stderr);}
#define _INFO(fmt,arg...) {fprintf(stderr, fmt, ##arg);fflush(stderr);}
#else
#define _DEBUG(fmt,arg...)
#define _ERROR(fmt,arg...)
#define _INFO(fmt,arg...)
#endif

template<int LEN=128>
class socket_address_storage_policy
{
public:
        struct sockaddr& sa()
        {
                return *reinterpret_cast<struct sockaddr*>(data);
        }

        int Length()
        {
                struct sockaddr& addr = sa();
                switch (addr.sa_family)
                {
                case AF_INET:
                        return sizeof(struct sockaddr_in);
                        break;
                case AF_INET6:
                        return sizeof(struct sockaddr_in6);
                        break;
                case AF_UNIX:
                        return sizeof(struct sockaddr_un);
                        break;
                default:
                        return 0;
                }
        }

        static int MaxSize() {return LEN;}
protected:
        char data[LEN];
};

template<class TSockAddr>
class socket_address_policy:public socket_address_storage_policy<sizeof(TSockAddr)>
{
public:
        typedef TSockAddr c_sockaddr_t;
        c_sockaddr_t& Addr()
        {
                struct sockaddr& addr = this->sa();
                return *reinterpret_cast<c_sockaddr_t*>(&addr);
        }
};

template<class TSockAddr, class TFd=int>
class socket_func_policy
{
public:
        typedef TSockAddr sock_addr_t;
        typedef socket_func_policy<TSockAddr, TFd> socket_t;
        typedef typename TSockAddr::c_sockaddr_t c_sockaddr_t;

        socket_func_policy()
        {
                fd = -1;
        }
        ~socket_func_policy()
        {
                Close();
        }

        bool Socket(int domain, int type, int protocol)
        {
                if (fd != -1)
                        return false;
                fd = ::socket(domain, type, protocol);
                if (fd == -1)
                        return false;
                _DEBUG("socket_func_policy: socket ok (%d)\n",fd);
                return true;
        }

        bool Bind(sock_addr_t& addr)
        {
                struct sockaddr& csa = addr.sa();
                int nCode = ::bind(fd, &csa, addr.Length());
                if (nCode != 0)
                        return false;
                _DEBUG("socket_func_policy: bind ok (%d)\n",fd);
                return true;
        }

        bool Listen(int backlog)
        {
                int nCode = ::listen(fd, backlog);
                if (nCode != 0)
                        return false;
                _DEBUG("socket_func_policy: listen ok (%d)\n",fd);
                return true;
        }

        bool Accept(socket_t& peer, sock_addr_t& addr)
        {
                socklen_t address_len = addr.MaxSize();
                peer.fd = ::accept(this->fd, &addr.sa(), &address_len);
                if (peer.fd <= 0)
                        return false;
                _DEBUG("socket_func_policy: accept ok (%d)->(%d)\n",fd,peer.fd);
                return true;
        }

        bool Connect(sock_addr_t& addr)
        {
                if (::connect(fd, &addr.sa(), addr.Length()) != 0)
                        return false;
                _DEBUG("socket_func_policy: connect ok (%d)\n",fd);
                return true;
        }

        bool Close()
        {
                if (fd == -1)
                        return false;
                if (close(fd) != 0)
                        return false;
                _DEBUG("socket_func_policy: close ok (%d)\n",fd);
                fd = -1;
                return true;
        }

        TFd fd;
};

template<class THost>
class unix_domain_serve_policy:
                public socket_func_policy<socket_address_policy<struct sockaddr_un> >
{
public:
        typedef unix_domain_serve_policy<THost> server_t;
        bool Open(const char* szPath, const char* szPort)
        {
                if (!this->Socket(AF_UNIX, SOCK_STREAM, 0))
                {
                        return false;
                }

                sock_addr_t addr;
                FillAddr(addr, szPath);

                if (!this->Bind(addr))
                {
                        _DEBUG("unix_domain_serve_policy: bind error [%s]\n",szPath);
                        return false;
                }

                if (!this->Listen(10))
                {
                        _DEBUG("unix_domain_serve_policy: listen error [%s]\n",szPath);
                        return false;
                }
                _DEBUG("unix_domain_serve_policy: listen on [%s]\n",szPath);
                return true;
        }

        bool FillAddr(sock_addr_t& addr, const char* szPath)
        {
                struct sockaddr_un& unAddr = addr.Addr();
                unAddr.sun_family = AF_UNIX;
                int nLen = sprintf(unAddr.sun_path, szPath)+1;
                nLen += sizeof(unAddr.sun_family);
                unlink(szPath);
                return true;
        }
};

template<class THost>
class unix_domain_client_policy:
                public socket_func_policy<socket_address_policy<struct sockaddr_un> >
{
public:
        typedef unix_domain_client_policy<THost> client_t;
        bool Open(const char* szPath, const char* szPort)
        {
                if (!this->Socket(AF_UNIX, SOCK_STREAM, 0))
                        return false;

                sock_addr_t addr;
                FillAddr(addr, szPath);

                if (!this->Connect(addr))
                {
                        _DEBUG("unix_domain_client_policy: connect error [%s] %d %s\n",szPath,errno,strerror(errno));
                        return false;
                }

                return true;
        }

        bool FillAddr(sock_addr_t& addr, const char* szPath)
        {
                struct sockaddr_un& unAddr = addr.Addr();
                unAddr.sun_family = AF_UNIX;
                int nLen = sprintf(unAddr.sun_path, szPath)+1;
                nLen += sizeof(unAddr.sun_family);
                //unlink(szPath);
                return true;
        }
};

template<class THost>
class epoll_policy
{
protected:
        typedef epoll_policy<THost> epoll_t;
        epoll_policy()
        {
                epollfd = -1;
        }
        ~epoll_policy()
        {
                Close();
        }
        bool Open(int nSize)
        {
                if (epollfd != -1)
                        return false;
                epollfd = epoll_create(nSize);
                if (epollfd == -1)
                        return false;
                _DEBUG("epoll_policy: epollfd = [%d]\n",epollfd);
                return true;
        }
        bool Add(int fd, int event, void* ptr)
        {
                struct epoll_event ev;
                ev.data.ptr = ptr;
                ev.events = event;//EPOLLIN EPOLLET;
                if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1)
                        return false;
                _DEBUG("epoll_policy: EPOLL_CTL_ADD = [%d]\n",fd);
                return true;
        }
        bool Mod(int fd, int event, void* ptr)
        {
                struct epoll_event ev;
                ev.data.ptr = ptr;
                ev.events = event;//EPOLLIN EPOLLET;
                if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev) == -1)
                        return false;
                _DEBUG("epoll_policy: EPOLL_CTL_MOD = [%d]\n",fd);
                return true;
        }
        bool Del(int fd, int event, void* ptr)
        {
                struct epoll_event ev;
                ev.data.ptr = ptr;
                ev.events = event;//EPOLLIN EPOLLET;
                if (epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev) == -1)
                        return false;
                _DEBUG("epoll_policy: EPOLL_CTL_DEL = [%d]\n",fd);
                return true;
        }
        bool Wait(struct epoll_event *events, int maxevents, int timeout)
        {
                int nfds = epoll_wait(epollfd, events, maxevents, timeout);
                if (nfds < 0)
                        return false;
                //_DEBUG("epoll_policy: epoll_wait = [%d]\n", nfds);
                struct epoll_event evNull = {0};
                events[nfds] = evNull;
                return true;
        }
        bool Close()
        {
                if (epollfd == -1)
                        return false;
                if (close(epollfd) != 0)
                        return false;
                epollfd = -1;
                return true;
        }
        int epollfd;
};

template<class THost>
class time_span_policy
{
protected:
        typedef time_span_policy<THost> time_span_t;
        void reset()
        {
                begin.tv_sec = 0;
                begin.tv_usec = 0;
                end = begin;
                dlt = begin;
        }
        void start()
        {
                gettimeofday(&begin,NULL);
        }
        void stop()
        {
                gettimeofday(&end,NULL);
                dlt.tv_sec += end.tv_sec - begin.tv_sec;
                dlt.tv_usec += end.tv_usec - begin.tv_usec;
        }
        int mseconds()
        {
                int ms = dlt.tv_sec*1000 + dlt.tv_usec/1000;
                return ms;
        }
        struct timeval begin;
        struct timeval end;
        struct timeval dlt;
};

template <
class THost,
template<class>class serve_policy,
template<class>class client_policy
>
class test_socket_policy:
                virtual public serve_policy<THost>,
                virtual public client_policy<THost>,
                public epoll_policy<THost>,
                public time_span_policy<THost>
{
public:
        typedef typename serve_policy<THost>::server_t server_t;
        typedef typename client_policy<THost>::client_t client_t;
        typedef typename epoll_policy<THost>::epoll_t epoll_t;
        typedef typename time_span_policy<THost>::time_span_t time_span_t;

        test_socket_policy(){};
        struct PeerInfo
        {
                typename server_t::socket_t sock;
                typename server_t::sock_addr_t addr;
                char* buf;
                char* buf1;
        };

        static int main(int argc, char* argv[])
        {
                THost tuds;
                tuds.argc = argc;
                tuds.argv = argv;
                tuds.nBlock = atoi(argv[4]);
                tuds.nTimes = atoi(argv[5]);
                tuds.ppi.buf = new char[tuds.nBlock];
                tuds.ppi.buf1 = new char[tuds.nBlock];
                for (int n=0; n<tuds.nBlock; n++) tuds.ppi.buf[n] = n%256;
                if ('A' <= argv[1][0] && argv[1][0] <= 'Z')
                        return tuds.server();
                if ('a' <= argv[1][0] && argv[1][0] <= 'z')
                        return tuds.client();
                delete[] tuds.ppi.buf;
                delete[] tuds.ppi.buf1;
                return -1;
        }
        int server()
        {
                _DEBUG("start unix domain socket server\n");
                if (!server_t::Open(argv[2],argv[3]))
                        return __LINE__;
                if (!epoll_t::Open(2))
                        return __LINE__;
                if (!epoll_t::Add(server_t::fd, EPOLLIN, this))
                        return __LINE__;
                struct epoll_event events[2+1];
                int timeout = 0;
                for (;;)
                {
                        if (!epoll_t::Wait(events, 3, timeout))
                                return __LINE__;
                        timeout = 5*1000;
                        for (int i=0; events[i].data.ptr != NULL; i++)
                        {
                                timeout = 0;
                                if (events[i].data.ptr == this)
                                {
                                        if (!server_t::Accept(ppi.sock, ppi.addr))
                                                return __LINE__;
                                        if (!epoll_t::Add(ppi.sock.fd, EPOLLIN, &ppi))
                                                return __LINE__;
                                        //ppi.fp = fopen(argv[3], "wb");
                                        if (!epoll_t::Del(server_t::fd, EPOLLIN, this))
                                                return __LINE__;
                                }
                                else if (events[i].data.ptr == &ppi)
                                {
                                        int nLen = recv(ppi.sock.fd, ppi.buf, nBlock, 0);
                                        if (nLen <= 0)
                                        {
                                                //fclose(ppi.fp);
                                                if (!epoll_t::Add(server_t::fd, EPOLLIN, this))
                                                        return __LINE__;
                                                if (!epoll_t::Del(ppi.sock.fd, 0, NULL))
                                                        return __LINE__;
                                                ppi.sock.Close();
                                        }
                                        else
                                        {
                                                //fwrite(ppi.buf, sizeof(char), nLen, ppi.fp);
                                        }
                                }
                                else
                                {
                                        return __LINE__;
                                }
                        }
                }
                return 0;
        }
        int client()
        {
                _DEBUG("start unix domain socket client\n");
                if (!client_t::Open(argv[2],argv[3]))
                        return __LINE__;
                time_span_t::reset();
                time_span_t::start();
                //ppi.fp = fopen(argv[3], "rb");
                //if (ppi.fp == NULL)
                //        return __LINE__;
                if (!epoll_t::Open(1))
                        return __LINE__;
                if (!epoll_t::Add(client_t::fd, EPOLLIN|EPOLLOUT, this))
                        return __LINE__;
                struct epoll_event events[1+1];
                int timeout = 0;
                for (;;)
                {
                        if (!epoll_t::Wait(events, 2, timeout))
                                return __LINE__;
                        timeout = 1000;
                        for (int i=0; events[i].data.ptr != NULL; i++)
                        {
                                timeout = 0;
                                if (events[i].data.ptr == this)
                                {
                                        if ((events[i].events&EPOLLOUT) != 0)
                                        {
                                                //int nLen = fread(ppi.buf, sizeof(char), sizeof(ppi.buf), ppi.fp);
                                                int nLen = nBlock;
                                                if (nLen > 0)
                                                {
                                                        int nSend = send(client_t::fd, ppi.buf, nLen, 0);
                                                        //memcpy(ppi.buf1,ppi.buf,nLen);
                                                        //memcpy(ppi.buf,ppi.buf1,nLen);
                                                        //int nSend = nLen;
                                                        if (nSend != nLen)
                                                        {
                                                                _DEBUG("client socket send(%d) != %d\n",nLen, nSend);
                                                                return __LINE__;
                                                        }
                                                        nTimes--;
                                                }
                                                if (nTimes == 0)
                                                {
                                                        client_t::Close();
                                                        time_span_t::stop();
                                                        _DEBUG("client timespan=%d\n", time_span_t::mseconds());
                                                        return 0;
                                                }
                                        }
                                }
                                else
                                {
                                        return __LINE__;
                                }
                        }
                }
                _DEBUG("client end\n");
                return __LINE__;
        }
        int argc;
        char** argv;
        PeerInfo ppi;
        int nBlock;
        int nTimes;
};

template<class THost>
class ipv4_serve_policy:
                public socket_func_policy<socket_address_policy<struct sockaddr_in> >
{
public:
        typedef ipv4_serve_policy<THost> server_t;
        bool Open(const char* szPath, const char* szPort)
        {
                if (!this->Socket(AF_INET, SOCK_STREAM, 0))
                {
                        return false;
                }

                sock_addr_t addr;
                FillAddr(addr, szPath, szPort);

                if (!this->Bind(addr))
                {
                        _DEBUG("ipv4_serve_policy: bind error [%s]\n",szPath);
                        return false;
                }

                if (!this->Listen(10))
                {
                        _DEBUG("ipv4_serve_policy: listen error [%s]\n",szPath);
                        return false;
                }
                _DEBUG("ipv4_serve_policy: listen on [%s:%s]\n",szPath,szPort);
                return true;
        }

        bool FillAddr(sock_addr_t& addr, const char* szPath, const char* szPort)
        {
                struct sockaddr_in& unAddr = addr.Addr();
                unAddr.sin_family = AF_INET;
                int nCode = inet_pton(AF_INET, szPath, &unAddr.sin_addr);
                if (nCode <= 0)
                        return false;
                unAddr.sin_port = ntohs(atoi(szPort));
                return true;
        }
};

template<class THost>
class ipv4_client_policy:
                public socket_func_policy<socket_address_policy<struct sockaddr_in> >
{
public:
        typedef ipv4_client_policy<THost> client_t;
        bool Open(const char* szPath, const char* szPort)
        {
                if (!this->Socket(AF_INET, SOCK_STREAM, 0))
                        return false;

                sock_addr_t addr;
                FillAddr(addr, szPath, szPort);

                if (!this->Connect(addr))
                {
                        _DEBUG("ipv4_client_policy: connect error [%s:%s] %d %s\n",szPath,szPort,errno,strerror(errno));
                        return false;
                }

                return true;
        }

        bool FillAddr(sock_addr_t& addr, const char* szPath, const char* szPort)
        {
                struct sockaddr_in& unAddr = addr.Addr();
                unAddr.sin_family = AF_INET;
                int nCode = inet_pton(AF_INET, szPath, &unAddr.sin_addr);
                if (nCode <= 0)
                        return false;
                unAddr.sin_port = ntohs(atoi(szPort));
                return true;
        }
};


class TestUnixDomainSocket:
                public test_socket_policy<
                TestUnixDomainSocket,
                unix_domain_serve_policy,
                unix_domain_client_policy>
{
};


class TestIpv4Socket:
                public test_socket_policy<
                TestIpv4Socket,
                ipv4_serve_policy,
                ipv4_client_policy>
{
};

int main(int argc, char* argv[], char* env[])
{
        /*
argv[0] U /tmp/.unix.domain.path port block times
argv[0] u /tmp/.unix.domain.path port block times

argv[0] S ip port block times
argv[0] s ip port block times

         */
        if (argc <= 2)
        {
                return -1;
        }
    if (argv[1][0] == 'U' || argv[1][0] == 'u')
    {
            TestUnixDomainSocket::main(argc, argv);
    }
    else if (argv[1][0] == 'S' || argv[1][0] == 's')
    {
               TestIpv4Socket::main(argc, argv);
    }
    return 0;
}
[/i][/i][/i][/i][/i][/i]

论坛徽章:
7
IT运维版块每日发帖之星
日期:2015-08-29 06:20:00IT运维版块每日发帖之星
日期:2015-08-29 06:20:00平安夜徽章
日期:2015-12-26 00:06:30技术图书徽章
日期:2016-02-03 16:35:252016猴年福章徽章
日期:2016-02-18 15:30:34fulanqi
日期:2016-06-17 17:54:25C
日期:2016-10-25 16:08:32
2 [报告]
发表于 2015-09-02 17:53 |只看该作者
太长了,自己先简单描述一下哪里感觉不对了 ..

论坛徽章:
154
2022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:5720周年集字徽章-年
日期:2022-10-26 16:44:2015-16赛季CBA联赛之深圳
日期:2022-11-02 14:02:4515-16赛季CBA联赛之八一
日期:2022-11-28 12:07:4820周年集字徽章-20	
日期:2023-07-19 08:49:4515-16赛季CBA联赛之八一
日期:2023-11-04 19:23:5115-16赛季CBA联赛之广夏
日期:2023-12-13 18:09:34
3 [报告]
发表于 2015-09-03 07:21 来自手机 |只看该作者
感觉学了cpp的人,写起代码基本都有点太得意的心态

感觉有能力玩弄高级特性了,其实也是慢慢学会把问题搞复杂化了

论坛徽章:
1
水瓶座
日期:2013-11-07 10:57:11
4 [报告]
发表于 2015-09-06 16:10 |只看该作者
太长了太长了太长了

论坛徽章:
11
2015年迎新春徽章
日期:2015-03-04 09:55:282017金鸡报晓
日期:2017-02-08 10:39:4215-16赛季CBA联赛之辽宁
日期:2016-12-15 10:24:1715-16赛季CBA联赛之佛山
日期:2016-11-30 09:04:2015-16赛季CBA联赛之江苏
日期:2016-04-29 15:56:1215-16赛季CBA联赛之同曦
日期:2016-04-12 13:21:182016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之山东
日期:2016-02-16 11:37:52每日论坛发贴之星
日期:2016-02-07 06:20:00程序设计版块每日发帖之星
日期:2016-02-07 06:20:0015-16赛季CBA联赛之新疆
日期:2018-01-09 16:25:37
5 [报告]
发表于 2015-09-07 13:46 |只看该作者
本帖最后由 bskay 于 2015-09-07 13:47 编辑
shang2010 发表于 2015-09-03 07:21
感觉学了cpp的人,写起代码基本都有点太得意的心态

感觉有能力玩弄高级特性了,其实也是慢慢学会把问题搞 ...


好像是这样的,开始是避免重复,后来就重复地"避免重复",
然后.....怎么说呢.....
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP