#ifndef SOCKET_MODULE_H
#define SOCKET_MODULE_H

#include <string>
#include <string.h>
#include <errno.h>
#include <sys/types.h>

#ifdef WIN32
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define ssize_t int
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <unistd.h>
#include <fcntl.h>
#endif

#define BUF_SIZE 1024*6

class TCPSocket
{
protected:
    TCPSocket();
    virtual ~TCPSocket();

    bool create();
    bool bind(unsigned short int port, const char *ip = NULL) const;
    bool listen(int backlog = 1) const;
    bool accept(TCPSocket &clientSocket) const;
    bool connect(unsigned short int port, const char *ip) const;
    bool reuseaddr() const;
public:
    bool close();
    int getfd() const{ return m_sockfd; }
    //flag: true=SetNonBlock, false=SetBlock
    bool setNonBlocking(bool flag) const;
protected:
    int m_sockfd;
};

/** TCP Client **/
class TCPClient : public TCPSocket
{
private:
    struct Packet
    {
        unsigned int    msgLen;     //数据部分的长度(网络字节序)
        char            text[BUF_SIZE]; //报文的数据部分
    };
public:
    TCPClient():m_bValid(false){}
    ~TCPClient(){}

    /* 该函数会强制删除现有socket重新创建连接 */
    bool doConnect(unsigned short port, const char *ip);
    bool read(void *buf, size_t count);
    bool write(const char *msg);
    bool receive(std::string& message);
    bool send(const std::string& message);
    void setSocketTimeout(int timeout);
    
    bool isValid(){ return m_bValid; }
    void setValid(bool valid){ m_bValid=valid; }
private:
    bool m_bValid;
};

/** TCP Server **/
class TCPServer : public TCPSocket
{
public:
    TCPServer(){}
    ~TCPServer(){}
    
    /* 该函数会强制删除现有socket重新创建监听 */
    bool doListen(unsigned short int port, const char *ip = NULL, int backlog = SOMAXCONN);
    bool accept(TCPSocket &clientSocket) const;
};

#endif
