#include 
"stdafx.h"
#include 
"libyfun.h"
#include 
"mytcp.h"
//#include "ty_server.h"

//构造函数
myCTcp::myCTcp ()
{
    m_timeout 
= 3000;
    m_nSock 
= -1;
    WSADATA sockData;
    
if (WSAStartup (MAKEWORD (22), &sockData))
    {
        printf(
"TCP加载失败\n");
        exit (
0);
    }
}

//析构函数
myCTcp::~myCTcp ()
{
    Close ();
    WSACleanup ();
}

/*赋值
  入参:nSockfd - socket句柄
  出参:赋值后的socket句柄
*/
int myCTcp::operator = (int nSockfd)
{
    assert ((m_nSock 
== -1&& (nSockfd > -1));
    m_nSock 
= nSockfd;

    
return m_nSock;
}

/*取出socket句柄
  入参:无
  出参:取出的socket句柄
*/
int myCTcp::GetHandle () const
{
    
return m_nSock;
}

/*创建socket
  入参:无
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::Open ()
{
    assert (m_nSock 
== -1);

    
if(m_nSock != -1)
        Close ();

    m_nSock 
= socket (AF_INET, SOCK_STREAM, 0);

    setsockopt (m_nSock, SOL_SOCKET, SO_SNDTIMEO, (
char *)&m_timeout, sizeof(m_timeout));

    setsockopt (m_nSock, SOL_SOCKET, SO_RCVTIMEO, (
char *)&m_timeout, sizeof(m_timeout));


    
return (m_nSock != -1);
}

/*关闭socket
  入参:无
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::Close ()
{
    
if (m_nSock != -1)
    {
        
if(closesocket (m_nSock) != 0)
        {
            
int err = WSAGetLastError();
//            DEBUG (gbl.is_debug, gbl.debug_level, gbl.log_file, "WSAGetLastError %d", err);
        }

        m_nSock 
= -1;    
    }
    
return 1;
}

/*连接
  入参:pHost - IP地址或主机名
      nPort - 端口
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::Connect (const char *pHost, int nPort) const
{
    assert ((m_nSock 
!= -1&& pHost && (nPort > 0));
    
struct sockaddr_in addr;
    
struct hostent *phe = NULL;

    memset (
&addr, 0sizeof (addr));
    addr.sin_family 
= AF_INET;
    addr.sin_port 
= htons (nPort);

    
if ((addr.sin_addr.s_addr = inet_addr (pHost)) == (unsigned long int-1)
    {
        
if ((phe = gethostbyname (pHost)) == NULL)
            
return 0;

        memcpy ((
char *)&addr.sin_addr, phe->h_addr, phe->h_length);
    }

    
return (connect (m_nSock, (struct sockaddr *)&addr, sizeof (addr)) == 0);
}

/*绑定
  入参:pIP - IP地址
      nPort - 端口
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::Bind (const char *pIP, int nPort) const
{
    assert ((m_nSock 
!= -1&& (nPort > 0));
    
struct sockaddr_in addr;
    
struct hostent *phe = NULL;
    
int opt=1;

    
if (setsockopt (m_nSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(int)) == -1)
    {    
        
return 0;
    }

    memset (
&addr, 0sizeof (addr));
    addr.sin_family 
= AF_INET;
    addr.sin_port 
= htons (nPort);

    
if (!pIP)
    {
        addr.sin_addr.s_addr 
= htonl (INADDR_ANY);
    }
    
else
    {
        
if ((addr.sin_addr.s_addr = inet_addr (pIP)) == (unsigned long int-1)
        {
            
if ((phe = gethostbyname (pIP)) == NULL)
                
return 0;

            memcpy ((
char *)&addr.sin_addr, phe->h_addr, phe->h_length);
        }
    }

    
return (bind (m_nSock, (struct sockaddr *)&addr, sizeof (addr)) == 0);
}

/*监听
  入参:nNum - 监听数目
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::Listen (int nNum) const
{
    assert ((m_nSock 
!= -1&& (nNum > 0));

    
return (listen (m_nSock, nNum) == 0);
}

/*接受连接
  入参:无
  出参:其他: 连接套接字句柄 ; -1: 失败
*/
int myCTcp::Accept () const
{
    assert (m_nSock 
!= -1);

    
return (accept (m_nSock, (struct sockaddr *)NULL, NULL));
}

/*发送指定数目数据
  入参:pBuf - 发送缓存
      nCount - 需发送字节数
      nMicsec - socket超时值,单位:微妙,缺省:500000微妙
  出参:实际发送字节数 ,如果发送失败,返回负数
*/
int myCTcp::Sendn (const void *pBuf, int nCount, int nMicsec) const
{
    assert ((m_nSock 
!= -1&& pBuf && (nCount > 0));
    
int nLeft = nCount, nWritten = 0;
    
const char *ptr = (const char *)pBuf;
    
    
while (nLeft > 0)
    {
        
if ((nWritten = send (m_nSock, ptr, nLeft, 0)) <= 0)
        {
            
return MY_SOCK_ERROR;
        }

        nLeft 
-= nWritten;
        ptr 
+= nWritten;
    }

    
return nCount;
}

/*接收指定数目数据
  入参:pBuf - 接收缓存
      nCount - 需接收字节数
      nMicsec - socket超时值,单位:微妙,缺省:500000微妙
  出参:实际接收字节数 ,如果接收失败,返回负数,如果对方关闭,返回0
*/
int myCTcp::Recvn (void *pBuf, int nCount, int nMicsec) const
{
     assert ((m_nSock 
!= -1&& pBuf && (nCount > 0));
    
int nLeft = nCount, nRead = 0;
    
char *ptr = (char *)pBuf;

    
while (nLeft > 0)
    {
        
if ((nRead = recv (m_nSock, ptr, nLeft, 0)) < 0)
        {
            
return MY_SOCK_ERROR;
        }
        
else if (nRead == 0)
        {
            
return 0;
        }

        nLeft 
-= nRead;
        ptr 
+= nRead;
    }

    
return nCount;
}

/*设置地址可重用
  入参:无
  出参:1: 成功 ; 0: 失败
*/
int myCTcp::SetReuseAddr ()
{
    assert (m_nSock 
!= -1);
    
int opt = 1;
    
    
if (setsockopt (m_nSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(int)) == -1)
    {
        
return 0;
    }
    
    
return 1;
}