//  Socket32.h: interface for the CSocket32 class.
//
/**/ //////////////////////////////////////////////////////////////////////

#if  !defined(AFX_SOCKET32_H__0C5B01C7_CACD_44E5_AB92_130605BBD66B__INCLUDED_)
#define  AFX_SOCKET32_H__0C5B01C7_CACD_44E5_AB92_130605BBD66B__INCLUDED_

#if  _MSC_VER > 1000
#pragma once
#endif   //  _MSC_VER > 1000

#ifdef _WIN32
#include 
< WinSock2.h >
typedef 
int  socklen_t ;
#else
#include 
< sys / socket.h >
#include 
< sys / types.h >
#include 
< netinet / in .h >
#include 
< arpa / inet.h >

#include 
< unistd.h >
#include 
< errno.h >
#include 
< sys / stat.h >
#include 
< string .h >
#include 
< netdb.h >
#ifndef CONST
#define  CONST               const
#endif

typedef unsigned 
char    u_char;
typedef unsigned 
short   u_short;
typedef unsigned 
int     u_int;
typedef unsigned 
long    u_long;
typedef u_int           SOCKET;

typedef 
int                  INT;
typedef unsigned 
int         UINT;
typedef unsigned 
int          * PUINT;
typedef unsigned 
long        DWORD;
typedef 
int                  BOOL;
typedef unsigned 
char        BYTE;
typedef unsigned 
short       WORD;
typedef 
float                FLOAT;
typedef FLOAT               
* PFLOAT;
typedef BOOL            
* PBOOL;
typedef BOOL             
* LPBOOL;
typedef BYTE            
* PBYTE;
typedef BYTE             
* LPBYTE;
typedef 
int               * PINT;
typedef 
int                * LPINT;
typedef WORD            
* PWORD;
typedef WORD             
* LPWORD;
typedef 
long               * LPLONG;
typedef DWORD           
* PDWORD;
typedef DWORD            
* LPDWORD;
typedef 
void               * LPVOID;
typedef CONST 
void         * LPCVOID;

#ifndef _TCHAR_DEFINED
typedef 
char  TCHAR,  * PTCHAR;
typedef unsigned 
char  TBYTE ,  * PTBYTE ;
#define  _TCHAR_DEFINED
#endif  /* !_TCHAR_DEFINED */

#ifndef VOID
#define  VOID void
typedef 
char  CHAR;
typedef 
short  SHORT;
typedef 
long  LONG;
#endif
typedef CHAR 
* PCHAR;
typedef CHAR 
* LPCH,  * PCH;

typedef CONST CHAR 
* LPCCH,  * PCCH;
typedef CHAR 
* NPSTR;
typedef CHAR 
* LPSTR,  * PSTR;
typedef CONST CHAR 
* LPCSTR,  * PCSTR;
typedef LPSTR LPTCH, PTCH;
typedef LPSTR PTSTR, LPTSTR;
typedef LPCSTR LPCTSTR;


#ifndef FALSE
#define  FALSE               0
#endif

#ifndef TRUE
#define  TRUE                1
#endif

#define  INVALID_SOCKET  (SOCKET)(~0)
#define  SOCKET_ERROR            (-1)
typedef 
struct  in_addr   * LPIN_ADDR;

#define  closesocket(x) close(x)


#endif

class  CSocket32  
{
    SOCKET m_hSocket;
    
public:
    BOOL Create( UINT nSocketPort 
= 0int nSocketType = SOCK_STREAM , LPCTSTR lpszSocketAddress = NULL );
    
int SendTo( const void* lpBuf, int nBufLen, UINT nHostPort, LPCSTR lpszHostAddress = NULL, int nFlags = 0 );
    
int ReceiveFrom( void* lpBuf, int nBufLen, char *rSocketAddress, UINT& rSocketPort, int nFlags = 0 );
    
    BOOL Listen( 
int nConnectionBacklog = 5 )
    
{
        
return !listen(m_hSocket,nConnectionBacklog);
    }

    
int Send( const void* lpBuf, int nBufLen, int nFlags = 0 )
    
{
        
return send(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
    }

    
int Receive( void* lpBuf, int nBufLen, int nFlags = 0 )
    
{
        
return recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
    }
    
    
void Close( )
    
{
        closesocket(m_hSocket);
    }


    BOOL GetSockName( 
char*  rSocketAddress, UINT& rSocketPort );
    BOOL GetPeerName(  
char* rPeerAddress, UINT& rPeerPort );
    BOOL Accept( CSocket32
& rConnectedSocket,  LPSTR lpSockAddr = NULL,UINT *nPort = NULL);
    BOOL Connect( LPCTSTR lpszHostAddress, UINT nHostPort );
        
    CSocket32();
    
virtual ~CSocket32();
    
}
;

#endif   //  !defined(AFX_SOCKET32_H__0C5B01C7_CACD_44E5_AB92_130605BBD66B__INCLUDED_)
//  Socket32.cpp: implementation of the CSocket32 class.
//
/**/ //////////////////////////////////////////////////////////////////////

#include 
" stdafx.h "
#include 
" Socket32.h "
#include 
< assert.h >

/**/ //////////////////////////////////////////////////////////////////////
//  Construction/Destruction
/**/ //////////////////////////////////////////////////////////////////////
// 构造
CSocket32::CSocket32()
{
#ifdef _WIN32
    WSAData wsaData;
    
int err =WSAStartup(0x0202,&wsaData);
    
if ( err != 0 )                           
        
return;
    
if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 )
    
{
        WSACleanup( );
        
return
    }

#endif
    m_hSocket 
= INVALID_SOCKET;
}

// 析构
CSocket32:: ~ CSocket32()
{
    Close();
}

/**/ /**********************************************************************/
// 1.创建套接字
BOOL CSocket32::Create( UINT nSocketPort,  int  nSocketType ,LPCTSTR lpszSocketAddress )
{
    assert(m_hSocket 
== INVALID_SOCKET);//套接字必须首先初始化为空
    m_hSocket = socket(AF_INET,nSocketType,IPPROTO_IP);//然后再创建
    if(    m_hSocket == INVALID_SOCKET)
        
return FALSE;

    sockaddr_in addr 
= {AF_INET,htons(nSocketPort)};
    
if (!lpszSocketAddress) //如果用户不指定,则系统分配
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
else
        addr.sin_addr.s_addr 
= inet_addr(lpszSocketAddress);
    
    
if (!bind(m_hSocket,(sockaddr*)&addr,sizeof(addr)))
        
return TRUE;//If no error occurs, bind returns zero
    Close();
    
    
return FALSE;
}


// 2.发送(针对UDP)
int  CSocket32::SendTo(  const   void *  lpBuf,  int  nBufLen, UINT nHostPort, LPCSTR lpszHostAddress ,  int  nFlags)
{
    sockaddr_in addr 
= {AF_INET,htons(nHostPort),};
    assert(lpszHostAddress);
//UDP 必须指定目的地址
    addr.sin_addr.s_addr = inet_addr(lpszHostAddress);
    
return sendto(m_hSocket,(char*)lpBuf,nBufLen,nFlags,(sockaddr*)&addr,sizeof(addr));
}


// 3.接收(针对UDP)
int  CSocket32::ReceiveFrom(  void *  lpBuf,  int  nBufLen,  char   * rSocketAddress, UINT &  rSocketPort,  int  nFlags )
{
    sockaddr_in from;
//必须设一个临时变量,分配内存,接收信息。
    socklen_t fromlen = sizeof(from);//然后才能计算内存长度
    
    
int nRet = recvfrom(m_hSocket,(LPSTR)lpBuf,nBufLen,nFlags,(sockaddr*)&from,&fromlen);
    
if(nRet <= 0)
        
return nRet;
    
if(rSocketAddress)
    
{
        strcpy(rSocketAddress,inet_ntoa(from.sin_addr));
//out
        rSocketPort = htons(from.sin_port);//out
    }


    
return nRet;
}


// 4.接受请求(针对TCP)
BOOL CSocket32::Accept( CSocket32 &  rConnectedSocket, LPSTR lpSockAddr ,UINT  * nPort )
{
    sockaddr_in addr 
= {AF_INET};
    socklen_t nLen 
= sizeof(addr);
    rConnectedSocket.m_hSocket 
= accept(m_hSocket,(sockaddr*)&addr,&nLen);
    
if(rConnectedSocket.m_hSocket == INVALID_SOCKET)
        
return FALSE;
    
if(lpSockAddr)
    
{
        strcpy(lpSockAddr,inet_ntoa(addr.sin_addr));
        
*nPort = htons(addr.sin_port);
    }

    
return TRUE;    
}


// 5.请求连接(针对TCP)
BOOL CSocket32::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
{
    sockaddr_in addr 
= {AF_INET,htons(nHostPort)};
    addr.sin_addr.s_addr 
= inet_addr(lpszHostAddress);
    
if (addr.sin_addr.s_addr == INADDR_NONE)//若是有限广播地址,则用本机地址之一
    {
        hostent 
* lphost = gethostbyname(lpszHostAddress);
        
if (lphost != NULL)
            addr.sin_addr.s_addr 
= ((LPIN_ADDR)lphost->h_addr)->s_addr;
        
else
        
{
            
//WSAGetLastError();
        
//    WSASetLastError(WSAEINVAL);
            return FALSE;
        }

    }

    
return !connect(m_hSocket,(sockaddr*)&addr,sizeof(addr));
}


// 6.得到本机套接字:IP:Port
BOOL CSocket32::GetSockName(  char *   rSocketAddress, UINT &  rSocketPort )
{
    sockaddr_in addr;
    socklen_t nLen 
= sizeof(addr);

    
if(SOCKET_ERROR == getsockname(m_hSocket, (sockaddr*)&addr, &nLen))
        
return FALSE;
    
if(rSocketAddress)
    
{
        strcpy(rSocketAddress,inet_ntoa(addr.sin_addr));
        rSocketPort 
= htons(addr.sin_port);
    }

    
return TRUE;
}


// 7.得到对方套接字名字:IP:Port
BOOL CSocket32::GetPeerName(   char *  rPeerAddress, UINT &  rPeerPort )
{
    sockaddr_in addr;
    socklen_t nLen 
= sizeof(addr);

    
if(SOCKET_ERROR == getpeername(m_hSocket, (sockaddr*)&addr, &nLen))
        
return FALSE;
    
if(rPeerAddress)
    
{
        strcpy(rPeerAddress,inet_ntoa(addr.sin_addr));
        rPeerPort 
= htons(addr.sin_port);
    }

    
return TRUE;
}