/************************************************************************/
/*  Copyright (C), 2016-2020, [IT], ��������Ȩ��;
/*  ģ �� ����SockAddrIn;
/*  ��    ����SockAddrIn�ṹ��,�ڲ���װ�� SOCKADDR_STORAGE (IPv4: SOCKADDR_IN, IPv6: SOCKADDR_IN6) �ṹ��;
/*
/*
/*  ��    ����[V];	
/*  ��    �ߣ�[IT];
/*  ��    �ڣ�[2/23/2016];
/*
/*
/*  ע    �⣺;
/*
/*  �޸ļ�¼��[IT];
/*  �޸����ڣ�;
/*  �޸İ汾��;
/*  �޸����ݣ�;
/************************************************************************/
#ifndef __SOCKADDRIN_20160303__
#define __SOCKADDRIN_20160303__

#pragma once

#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#elif BSD_SOCKET
#include "platform.h"
#endif

struct SockAddrIn : public sockaddr_storage 
{
public:
	SockAddrIn();
	~SockAddrIn();

	// ��������;
	SockAddrIn(IN const SockAddrIn& sin);
	// ���ƺ���;
	SockAddrIn& Copy(IN const SockAddrIn& sin);
	// ��սṹ��;
	void Clear();
	// �Աȵ�ַ�Ƿ���ͬ;
	bool IsEqual(IN const SockAddrIn& sin) const;
	// ���NULLAddr��Ч,����TRUE;
	bool IsNull() const { return IsEqual(NULLAddr); }
	// ���ص�ַ������;
	short GetFamily() const { return ss_family; }
	// ����IPV4�����ַ;
	ULONG GetIPAddr() const { return ((SOCKADDR_IN*)this)->sin_addr.s_addr; }
	// ��ȡ����˿�;
	short GetPort() const { return ((SOCKADDR_IN*)this)->sin_port; }
	// ��������˵�ַ(ͬʱ֧��IPV4��IPV6);
	bool CreateFrom(IN LPCTSTR pszAddr, IN LPCTSTR pszService, IN int nFamily = AF_INET, bool bIsClient = true);
	// ��������˵�ַ(ֻ֧��IPV4);
	bool CreateFrom(IN ULONG lIPAddr, IN USHORT nPort, IN int nFamily = AF_INET, IN bool bFmtHost = true);
	// ��ֵ��������,����thisָ������;
	SockAddrIn& operator=(const SockAddrIn& sin) { return Copy( sin ); }
	// ��Ȳ����ж�,��ȷ���TRUE;
	bool operator==(const SockAddrIn& sin) const { return IsEqual( sin ); }
	// ���Ȳ����ж�,�����ͬ����TRUE;
	bool operator!=(const SockAddrIn& sin) const { return !IsEqual( sin ); }
	// ת��SOCKADDR��ַ,����SOCKADDR��ʽ��this����;
	operator LPSOCKADDR() { return reinterpret_cast<LPSOCKADDR>(this); }
	// ת��PIN6_ADDR��ַ,����PIN6_ADDR��ʽ��this����;
	operator const IN6_ADDR*() const { return reinterpret_cast<const IN6_ADDR*>(this); }
	// ת��PIN6_ADDR��ַ,����PIN6_ADDR��ʽ��this����;
	operator PIN6_ADDR() { return reinterpret_cast<PIN6_ADDR>(this); }
	// ���ؽṹ��(SOCKADDR_IN) �� (SOCKADDR_STORAGE)�Ĵ�С(�ɵ�ַЭ��ؾ���);
	size_t Size() const { return (ss_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_storage); }
	// ��SOCKADDR_IN�ṹ������ʼ��this����;
	void SetAddr(IN const sockaddr_in* psin) { SetAddr(reinterpret_cast<const sockaddr_storage*>(psin)); }
	// ��SOCKADDR_IN6�ṹ������ʼ��this����;
	void SetAddr(IN const sockaddr_in6* psin) { SetAddr(reinterpret_cast<const sockaddr_storage*>(psin)); }
	// ��SOCKADDR_STROAGE�ṹ������ʼ��this����;
	void SetAddr(IN const sockaddr_storage* pss) { ss_family = pss->ss_family; memcpy(this, pss, Size()); }

	// �յĵ�ֵַ�����ڱȽ���һ��ַ�Ƿ��;
	static SockAddrIn NULLAddr;    
};

#endif

/* // IPV4��ַ�ṹ;
/* struct SOCKADDR_IN{
/*		SHORT				sin_family;		// ��ַ��;
/*		USHORT				sin_port;		// �˿ں�;
/*		in_addr				sin_addr;		// ��ַ;
/*		CHAR				sin_zero[8];	// IPV4Ϊ�����ṹ�������̶ֹ���С,������;	
/* };
/* 
/* struct IN_ADDR{
/*		unsigned long		s_addr;			// ��ַ;
/* };
/* 
/* // IPV6��ַ�ṹ;
/* struct SOCKADDR_IN6{
/*		USHORT				sin6_family;	// ��ַ������:AF_INET6;
/*		USHORT				sin6_port;		// 16λ�˿ں�;
/*		ULONG				sin6_flowinfo;	// 32λ����ǩ;
/*		in6_addr			sin6_addr;		// 128λIP��ַ;
/*		union
/*		{
/*			ULONG sin6_scope_id;     // Set of interfaces for a scope.
/*			SCOPE_ID sin6_scope_struct; 
/*		};
/* };
/* 
/* struct in6_addr {
/*		union {
/*			UCHAR       Byte[16];
/*			USHORT      Word[8];
/*		} u;
/* } ;
/* 
/* typedef struct {
/*		union {
/*			struct 
/*			{
/*				ULONG Zone : 28;
/*				ULONG Level : 4;
/*			};
/*		ULONG Value;
/*	};
/* } SCOPE_ID, *PSCOPE_ID;
*/