项目框架(3):socket通讯的客户端类

.h文件

// socket通讯的客户端类
class ctcpclient
{
private:
    int  m_connfd;    // 客户端的socket.
    string m_ip;        // 服务端的ip地址。
    int  m_port;        // 服务端通讯的端口。
public:
    ctcpclient(): m_connfd(-1),m_port(0) { }  // 构造函数。

    // 向服务端发起连接请求。
    // ip:服务端的ip地址。
    // port:服务端通讯的端口。
    // 返回值:true-成功;false-失败。
    bool connect(const string &ip,const int port);

    // 接收对端发送过来的数据。
    // buffer:存放接收数据缓冲区。
    // ibuflen: 打算接收数据的大小。
    // itimeout:等待数据的超时时间(秒):-1-不等待;0-无限等待;>0-等待的秒数。
    // 返回值:true-成功;false-失败,失败有两种情况:1)等待超时;2)socket连接已不可用。
    bool read(string &buffer,const int itimeout=0);                           // 接收文本数据。
    bool read(void *buffer,const int ibuflen,const int itimeout=0);   // 接收二进制数据。

    // 向对端发送数据。
    // buffer:待发送数据缓冲区。
    // ibuflen:待发送数据的大小。
    // 返回值:true-成功;false-失败,如果失败,表示socket连接已不可用。
    bool write(const string &buffer);                          // 发送文本数据。
    bool write(const void *buffer,const int ibuflen);   // 发送二进制数据。

    // 断开与服务端的连接
    void close();

    ~ctcpclient();  // 析构函数自动关闭socket,释放资源。
};

向服务器发起连接,connect()的实现

bool ctcpclient::connect(const string &ip,const int port)
{
    // 如果已连接到服务端,则断开
    if(m_connfd!=-1){::close(m_connfd); m_connfd=-1}
    
    // 忽略SIGPIPE信号,防止程序异常退出。
    // 如果send到一个disconnected socket上,内核就会发出SIGPIPE信号。这个信号
    // 的缺省处理方法是终止进程,大多数时候这都不是我们期望的。我们重新定义这
    // 个信号的处理方法,大多数情况是直接屏蔽它。
    signal(SIGPIPE,SIG_IGN);

    m_ip=ip;
    m_port=port;

    struct hostent* h;
    struct sockaddr_in servaddr;

    if(m_connfd = socket(AF_INET, SOCK_STREAM,0)) <0 ) return false;
    
    if( !(h = gethostbyname(m_ip.c_str())) ){
        ::close(m_connfd); m_connfd=-1;return false;
    }

    memset(&servaddr, 0, sizeof(struct sockaddr_in));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(m_port); // 指定服务器端口
    memcpy(&servaddr.sin_addr,h->h_addr, h->h_length);

    if(::connect(m_connfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0){
        ::close(m_connfd);  m_connfd=-1; return false;
    }
    return true;
}

接收数据

其中tcpread()、tcpwrite()、readn()、writen(),见框架(2):服务端类

// 接收二进制数据。
bool ctcpclient::read(void *buffer,const int ibuflen,const int itimeout)   
{
    if (m_connfd==-1) return false;

    return(tcpread(m_connfd,buffer,ibuflen,itimeout));
}

// 接收文本数据。
bool ctcpclient::read(string &buffer,const int itimeout)  
{
    if (m_connfd==-1) return false;

    return(tcpread(m_connfd,buffer,itimeout));
}

发送数据

bool ctcpclient::write(const void *buffer,const int ibuflen)
{
    if (m_connfd==-1) return false;

    return(tcpwrite(m_connfd,(char*)buffer,ibuflen));
}

bool ctcpclient::write(const string &buffer)
{
    if (m_connfd==-1) return false;

    return(tcpwrite(m_connfd,buffer));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值