• Linux socket 类封装 (面向对象方法)


     1 /*
     2  * socketfactory.h
     3  *
     4  *  Created on: 2014-7-19
     5  *      Author: root
     6  */
     7 
     8 #ifndef SOCKETFACTORY_H_
     9 #define SOCKETFACTORY_H_
    10 #include<sys/types.h>
    11 
    12 /*
    13  * 在网路编程中, 一般分为服务端和客户端,两者的行为有相似之处,也有非常多的不同。在linux中对socket程序设计
    14  * 仅提供了socket(), bind(), connection(), accept() listern() 几个函数,并未区分是服务端还是客户端。
    15  * 在java或其他高级语言中,一般都对socket进行了封装,简化使用。
    16  *  此端程序将linux socket进行封装在三个类中。一个工厂类,两个接口类。
    17  *
    18  */
    19 
    20 namespace socketfactory {
    21 
    22 class ISocket;
    23 class IServerSocket;
    24 
    25 /*
    26  * SocketFactory 负责创建 ISocket, IServerSocket 的实例,同时负责销毁实例。
    27  * SocketFactory的方法全部是静态方法。此处采用了工厂模式。
    28  *
    29   */
    30 class SocketFactory {
    31 public:
    32     static ISocket* createSocket(const char* tIP, int tPort);    /* 创建客户端 socket */
    33     static IServerSocket* createServerSocket(int port);            /* 创建服务端 socket */
    34     static int destroy(ISocket* psocket);                                /* 销毁 */
    35     static int destroy(IServerSocket* psocket);                        /* 销毁 */
    36 };
    37 
    38 /*
    39  * ISocket 为接口,定义为纯虚类。面向接口编程
    40  *
    41  */
    42 
    43 class ISocket {
    44 public:
    45     virtual int read(void* buf, size_t len)=0;        /*    读取对端数据 */
    46     virtual int write(void* buf, size_t len)=0;        /* 写入对端数据 */
    47     virtual int close()=0;                                    /* 关闭连接 */
    48 };
    49 
    50 /*
    51  * IServerSocket 为接口,定义为纯虚类。面向接口编程。
    52  *
    53  */
    54 
    55 class IServerSocket {
    56 public:
    57     virtual ISocket* accept()=0;                        /* 接受连接,返回与对端通信的socket */
    58     virtual int listen(int backlog)=0;                /*    启动服务端口 监听 */
    59     virtual int close()=0;                                /* 关闭 服务端 socket */
    60 };
    61 
    62 }
    63 
    64 #endif /* SOCKETFACTORY_H_ */

    实现类的头文件

     1 /*
     2  * socketimpl.h
     3  *
     4  *  Created on: 2014-7-20
     5  *      Author: root
     6  */
     7 
     8 #ifndef SOCKETIMPL_H_
     9 #define SOCKETIMPL_H_
    10 #include <sys/socket.h>
    11 #include <netinet/in.h>
    12 #include "socketfactory.h"
    13 
    14 using namespace socketfactory;
    15 
    16 /*
    17  * ISocket 和 IServerSocket 的实现类。
    18  *  SocketFactory工厂类创建这些实现类。
    19  *
    20  */
    21 
    22 class SocketImpl: public ISocket
    23 {
    24 public:
    25     int read(void* buf, size_t len);
    26     int write(void* buf, size_t len);
    27     int close();
    28 
    29     int ssocket(int domain, int type, int protocol);
    30     int cconnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    31     SocketImpl();
    32     virtual ~SocketImpl();
    33 
    34 public:
    35     int fd;
    36     struct sockaddr  address;
    37 };
    38 
    39 
    40 class ServerSocketImpl: public IServerSocket
    41 {
    42 public:
    43     ISocket* accept();
    44     int listen(int backlog);
    45     int close();
    46 
    47 
    48     int ssocket(int domain, int type, int protocol);
    49     int bbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    50     ServerSocketImpl();
    51     virtual ~ServerSocketImpl();
    52 
    53 public:
    54     int fd;
    55     struct sockaddr  address;
    56 };
    57 
    58 
    59 #endif /* SOCKETIMPL_H_ */
      1 /*
      2  * socketimpl.cpp
      3  *
      4  *  Created on: 2014-7-20
      5  *      Author: root
      6  */
      7 
      8 #include <unistd.h>
      9 #include "socketimpl.h"
     10 #include <sys/types.h>
     11 #include <sys/socket.h>
     12 
     13 #include <stdio.h>
     14 
     15 
     16 SocketImpl::SocketImpl() {
     17     this->fd = -1;
     18 }
     19 
     20 int SocketImpl::ssocket(int domain, int type, int protocol) {
     21     this->fd = socket(domain, type, protocol);
     22     if (this->fd < 0)
     23         perror("SocketImpl::ssocket");
     24     return this->fd;
     25 }
     26 
     27 int SocketImpl::cconnect(int sockfd, const struct sockaddr *addr,
     28         socklen_t addrlen) {
     29     int ret = connect(sockfd, addr, addrlen);
     30     if (ret != 0)
     31         perror("SocketImpl::cconnect");
     32     return ret;
     33 
     34 }
     35 
     36 SocketImpl::~SocketImpl() {
     37 
     38 }
     39 
     40 int SocketImpl::read(void* buf, size_t len) {
     41     int ret = ::read(this->fd, buf, len);
     42     if (ret < 0)
     43         perror("SocketImpl::read");
     44     return ret;
     45 }
     46 ;
     47 
     48 int SocketImpl::write(void* buf, size_t len) {
     49     int ret = ::write(this->fd, buf, len);
     50     if (ret < 0)
     51         perror("SocketImpl::write");
     52     return ret;
     53 }
     54 ;
     55 
     56 int SocketImpl::close() {
     57     if (this->fd > 0) {
     58         int ret = ::close(this->fd);
     59         if (ret != 0)
     60         {
     61             perror("SocketImpl::close");
     62             return ret;
     63         }else
     64             this->fd = -1;
     65     }
     66     return 0;
     67 }
     68 
     69 ServerSocketImpl::ServerSocketImpl() {
     70     this->fd = 0;
     71 }
     72 
     73 ServerSocketImpl::~ServerSocketImpl() {
     74 }
     75 
     76 int ServerSocketImpl::ssocket(int domain, int type, int protocol) {
     77     this->fd = socket(domain, type, protocol);
     78     if (this->fd < 0)
     79         perror("ServerSocketImpl::ssocket");
     80     return this->fd;
     81 }
     82 
     83 int ServerSocketImpl::bbind(int sockfd, const struct sockaddr *addr,
     84         socklen_t addrlen) {
     85     int ret = bind(this->fd, addr, addrlen);
     86     if (ret < 0)
     87         perror("ServerSocketImpl::bbind");
     88     return ret;
     89 }
     90 
     91 ISocket* ServerSocketImpl::accept() {
     92     SocketImpl* nsocket = new SocketImpl();
     93     int addlen=0;
     94     int nfd =  ::accept(this->fd, &nsocket->address, (socklen_t*)&addlen);
     95     if (nfd == -1) {
     96         delete nsocket;
     97         perror("ServerSocketImpl::accept");
     98         return NULL;
     99     }
    100     nsocket->fd = nfd;
    101     return nsocket;
    102 }
    103 
    104 int ServerSocketImpl::listen(int backlog) {
    105     int ret = ::listen(this->fd, backlog);
    106     if (ret < 0)
    107         perror("ServerSocketImpl::listen");
    108     return ret;
    109 }
    110 
    111 int ServerSocketImpl::close() {
    112     if(this->fd >0 )
    113     {
    114         int ret=::close(this->fd);
    115         if(ret!=0 )
    116         {
    117             perror("ServerSocketImpl::close");
    118             return ret;
    119         }else
    120             this->fd =-1;
    121     }
    122     return 0;
    123 }
    /*
     * socketfactory.cpp
     *
     *  Created on: 2014-7-20
     *      Author: root
     */
    
    #include "socketfactory.h"
    #include "socketimpl.h"
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <stdio.h>
    #include <arpa/inet.h>
    
    
    ISocket* SocketFactory::createSocket(const char* tIP, int tPort)
    {
        SocketImpl*  nsocket=new SocketImpl();
        memset(&nsocket->address, 0, sizeof(sockaddr));
        struct sockaddr_in* padd=(sockaddr_in*)(&nsocket->address);
        padd->sin_family=AF_INET;
        padd->sin_port=htons(tPort);
        if( inet_pton(AF_INET, tIP, &padd->sin_addr) <= 0){
            delete nsocket;
            perror("SocketFactory::createSocket:inet_pton");
            return NULL;
        }
        int ret=nsocket->ssocket(AF_INET, SOCK_STREAM, 0);
        if(ret < 0 ){
            perror("SocketFactory::createSocket:ssocket");
            delete nsocket;
            return NULL;
        }
        ret=nsocket->cconnect(nsocket->fd, &nsocket->address, sizeof(sockaddr));
        if(ret < 0 ){
            perror("SocketFactory::createSocket:cconnect");
            nsocket->close();
            delete nsocket;
            return NULL;
        }
        return nsocket;
    }
    
    IServerSocket* SocketFactory::createServerSocket(int port)
    {
        ServerSocketImpl *nssocket=new ServerSocketImpl();
        memset(&nssocket->address, 0, sizeof(sockaddr));
        struct sockaddr_in* padd=(sockaddr_in*)(&nssocket->address);
        padd->sin_family=AF_INET;
        padd->sin_addr.s_addr=htonl(INADDR_ANY);
        padd->sin_port=htons(port);
        int ret=nssocket->ssocket(AF_INET, SOCK_STREAM, 0);
        if(ret<0){
            perror("SocketFactory::createServerSocket:ssocket");
            delete nssocket;
            return NULL;
        }
        ret=nssocket->bbind(nssocket->fd, &nssocket->address, sizeof(sockaddr));
        if(ret<0){
            perror("SocketFactory::createServerSocket:bbind");
            nssocket->close();
            delete nssocket;
            return NULL;
        }
        return nssocket;
    }
    
    int SocketFactory::destroy(ISocket* psocket)
    {
        SocketImpl* psockimpl=(SocketImpl*)psocket;
        psockimpl->close();
        delete psockimpl;
        return 0;
    }
    
    int SocketFactory::destroy(IServerSocket* psocket)
    {
        ServerSocketImpl* pssocket=(ServerSocketImpl*)psocket;
        pssocket->close();
        delete pssocket;
        return 0;
    }
  • 相关阅读:
    (数据科学学习手札09)系统聚类算法Python与R的比较
    写完代码就去吃饺子|The 10th Henan Polytechnic University Programming Contest
    《四月物语》
    PAT(甲级)2017年春季考试
    PAT(甲级)2017年秋季考试
    2019年全国高校计算机能力挑战赛 C语言程序设计决赛
    CF#603 Div2
    redhat7 上安装dummynet
    cassandra 如何写数据以及放置副本
    Eclipse中设置VM参数
  • 原文地址:https://www.cnblogs.com/piepie/p/3857618.html
Copyright © 2020-2023  润新知