// 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;
}