当客户端连接多个服务端,或者服务端连接其它服务端,或者是交叉的应用时,使用C语言的方式编写代码是不合适的。
C++面向对象编程为解决这类问题提供的方案。通过对客户端的业务逻辑进行封装,使得一个程序中建立不同的客户端对象来进行复杂的业务,并且使用类去封装服务端和客户端功能,更加简单易用。
本节对客户端进行封装,一个客户端程序能够支持连接多个服务器。(在实际的开发中,这种情况是必然存在的。有可能一个客户端需要连接登陆数据库、业务处理服务器等);
新建一个EasyTcpClient.hpp文件,对类的定义和实现都写在同一个文件中。
//保证此文件的代码只被编译一次
#ifndef EasyTcpClient_hpp_
#define EasyTcpClient_hpp_
#endif
#ifndef EasyTcpClient_hpp_
#define EasyTcpClient_hpp_
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<Windows.h>
#include<WinSock2.h>
#pragma comment(lib,"ws2_32.lib") //windows socket2 32的lib库
#else
#include<unistd.h>
#include<arpa/inet.h>
#include<string.h>
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#endif
#include<iostream>
#include"MessageHeadr.hpp"
using namespace std;
class EasyTcpClient //服务端的类,对其进行封装,使它的初始化、连接服务器、查询select请求、收发数据封装位类的成员函数。
{
public:
SOCKET _sock;
public:
EasyTcpClient()
{
_sock = INVALID_SOCKET;
}
//虚析构函数 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏。
//具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。
//假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,
//因而只会调