?? winsock.cxx
字號:
}
//////////////////////////////////////////////////////////////////////////////
// PIPSocket
PIPSocket::Address::Address(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
{
S_un.S_un_b.s_b1 = b1;
S_un.S_un_b.s_b2 = b2;
S_un.S_un_b.s_b3 = b3;
S_un.S_un_b.s_b4 = b4;
}
PIPSocket::Address::Address(DWORD dw)
{
S_un.S_addr = dw;
}
PIPSocket::Address & PIPSocket::Address::operator=(DWORD dw)
{
S_un.S_addr = dw;
return *this;
}
PIPSocket::Address::operator DWORD() const
{
return S_un.S_addr;
}
BYTE PIPSocket::Address::Byte1() const
{
return S_un.S_un_b.s_b1;
}
BYTE PIPSocket::Address::Byte2() const
{
return S_un.S_un_b.s_b2;
}
BYTE PIPSocket::Address::Byte3() const
{
return S_un.S_un_b.s_b3;
}
BYTE PIPSocket::Address::Byte4() const
{
return S_un.S_un_b.s_b4;
}
BOOL P_IsOldWin95()
{
static int state = -1;
if (state < 0) {
state = 1;
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
if (GetVersionEx(&info)) {
state = 0;
if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && info.dwBuildNumber < 1000)
state = 1;
}
}
return state != 0;
}
BOOL PIPSocket::IsLocalHost(const PString & hostname)
{
if (hostname.IsEmpty())
return TRUE;
if (hostname *= "localhost")
return TRUE;
// lookup the host address using inet_addr, assuming it is a "." address
Address addr = hostname;
if (addr == 16777343) // Is 127.0.0.1
return TRUE;
if (addr == 0) {
if (!GetHostAddress(hostname, addr))
return FALSE;
}
struct hostent * host_info = ::gethostbyname(GetHostName());
if (P_IsOldWin95())
return addr == Address(*(struct in_addr *)host_info->h_addr_list[0]);
for (PINDEX i = 0; host_info->h_addr_list[i] != NULL; i++) {
if (addr == Address(*(struct in_addr *)host_info->h_addr_list[i]))
return TRUE;
}
return FALSE;
}
#ifndef _WIN32_WCE
//////////////////////////////////////////////////////////////////////////////
// PIPXSocket
PIPXSocket::Address::Address()
{
memset(this, 0, sizeof(*this));
}
PIPXSocket::Address::Address(const Address & addr)
{
memcpy(this, &addr, sizeof(*this));
}
PIPXSocket::Address::Address(const PString & str)
{
PINDEX colon = str.Find(':');
if (colon == P_MAX_INDEX)
colon = 0;
else {
DWORD netnum = 0;
for (PINDEX i = 0; i < colon; i++) {
int c = str[i];
if (isdigit(c))
netnum = (netnum << 4) + c - '0';
else if (isxdigit(c))
netnum = (netnum << 4) + toupper(c) - 'A' + 10;
else {
memset(this, 0, sizeof(*this));
return;
}
}
network.dw = ntohl(netnum);
}
memset(node, 0, sizeof(node));
int shift = 0;
PINDEX byte = 5;
PINDEX pos = str.GetLength();
while (--pos > colon) {
int c = str[pos];
if (c != '-') {
if (isdigit(c))
node[byte] |= (c - '0') << shift;
else if (isxdigit(c))
node[byte] |= (toupper(c) - 'A' + 10) << shift;
else {
memset(this, 0, sizeof(*this));
return;
}
if (shift == 0)
shift = 4;
else {
shift = 0;
byte--;
}
}
}
}
PIPXSocket::Address::Address(DWORD netNum, const char * nodeNum)
{
network.dw = netNum;
memcpy(node, nodeNum, sizeof(node));
}
PIPXSocket::Address & PIPXSocket::Address::operator=(const Address & addr)
{
memcpy(this, &addr, sizeof(*this));
return *this;
}
PIPXSocket::Address::operator PString() const
{
return psprintf("%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X",
network.b.b1, network.b.b2, network.b.b3, network.b.b4,
node[0], node[1], node[2], node[3], node[4], node[5]);
}
BOOL PIPXSocket::Address::IsValid() const
{
static Address empty;
return memcmp(this, &empty, sizeof(empty)) != 0;
}
PIPXSocket::PIPXSocket(WORD newPort)
{
SetPort(newPort);
}
PString PIPXSocket::GetName() const
{
Address addr;
if (((PIPXSocket*)this)->GetPeerAddress(addr))
return addr;
else
return PString();
}
BOOL PIPXSocket::OpenSocket()
{
return ConvertOSError(os_handle = os_socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX));
}
const char * PIPXSocket::GetProtocolName() const
{
return "ipx";
}
BOOL PIPXSocket::SetPacketType(int type)
{
return ConvertOSError(::setsockopt(os_handle,
NSPROTO_IPX, IPX_PTYPE, (char *)&type, sizeof(type)));
}
int PIPXSocket::GetPacketType()
{
int value;
int valSize = sizeof(value);
if (ConvertOSError(::getsockopt(os_handle,
NSPROTO_IPX, IPX_PTYPE, (char *)&value, &valSize)))
return value;
return -1;
}
PString PIPXSocket::GetHostName(const Address & addr)
{
return addr;
}
BOOL PIPXSocket::GetHostAddress(Address &)
{
return FALSE;
}
static void AssignAddress(sockaddr_ipx & sip, const PIPXSocket::Address & addr)
{
memcpy(sip.sa_netnum, &addr.network, sizeof(sip.sa_netnum));
memcpy(sip.sa_nodenum, addr.node, sizeof(sip.sa_nodenum));
}
static void AssignAddress(PIPXSocket::Address & addr, const sockaddr_ipx & sip)
{
memcpy(&addr.network, sip.sa_netnum, sizeof(addr.network));
memcpy(addr.node, sip.sa_nodenum, sizeof(addr.node));
}
BOOL PIPXSocket::GetHostAddress(const PString & hostname, Address & addr)
{
addr = hostname;
if (addr.IsValid())
return TRUE;
static GUID netware_file_server = SVCID_FILE_SERVER;
CSADDR_INFO addr_info[10];
DWORD buffer_length = sizeof(addr_info);
int num = GetAddressByName(NS_DEFAULT,
&netware_file_server,
(LPTSTR)(const char *)hostname,
NULL,
0,
NULL,
addr_info,
&buffer_length,
NULL,
NULL
);
if (num <= 0)
return FALSE;
AssignAddress(addr, *(sockaddr_ipx *)addr_info[0].RemoteAddr.lpSockaddr);
return TRUE;
}
BOOL PIPXSocket::GetLocalAddress(Address & addr)
{
sockaddr_ipx sip;
int size = sizeof(sip);
if (!ConvertOSError(::getsockname(os_handle, (struct sockaddr *)&sip, &size)))
return FALSE;
AssignAddress(addr, sip);
return TRUE;
}
BOOL PIPXSocket::GetLocalAddress(Address & addr, WORD & portNum)
{
sockaddr_ipx sip;
int size = sizeof(sip);
if (!ConvertOSError(::getsockname(os_handle, (struct sockaddr *)&sip, &size)))
return FALSE;
AssignAddress(addr, sip);
portNum = Net2Host(sip.sa_socket);
return TRUE;
}
BOOL PIPXSocket::GetPeerAddress(Address & addr)
{
sockaddr_ipx sip;
int size = sizeof(sip);
if (!ConvertOSError(::getpeername(os_handle, (struct sockaddr *)&sip, &size)))
return FALSE;
AssignAddress(addr, sip);
return TRUE;
}
BOOL PIPXSocket::GetPeerAddress(Address & addr, WORD & portNum)
{
sockaddr_ipx sip;
int size = sizeof(sip);
if (!ConvertOSError(::getpeername(os_handle, (struct sockaddr *)&sip, &size)))
return FALSE;
AssignAddress(addr, sip);
portNum = Net2Host(sip.sa_socket);
return TRUE;
}
BOOL PIPXSocket::Connect(const PString & host)
{
Address addr;
if (GetHostAddress(host, addr))
return Connect(addr);
return FALSE;
}
BOOL PIPXSocket::Connect(const Address & addr)
{
// close the port if it is already open
if (IsOpen())
Close();
// make sure we have a port
PAssert(port != 0, "Cannot connect socket without setting port");
// attempt to create a socket
if (!OpenSocket())
return FALSE;
// attempt to lookup the host name
sockaddr_ipx sip;
memset(&sip, 0, sizeof(sip));
sip.sa_family = AF_IPX;
AssignAddress(sip, addr);
sip.sa_socket = Host2Net(port); // set the port
if (ConvertOSError(os_connect((struct sockaddr *)&sip, sizeof(sip))))
return TRUE;
os_close();
return FALSE;
}
BOOL PIPXSocket::Listen(unsigned, WORD newPort, Reusability reuse)
{
// make sure we have a port
if (newPort != 0)
port = newPort;
// close the port if it is already open
if (!IsOpen()) {
// attempt to create a socket
if (!OpenSocket())
return FALSE;
}
// attempt to listen
if (SetOption(SO_REUSEADDR, reuse == CanReuseAddress ? 1 : 0)) {
// attempt to listen
sockaddr_ipx sip;
memset(&sip, 0, sizeof(sip));
sip.sa_family = AF_IPX;
sip.sa_socket = Host2Net(port); // set the port
if (ConvertOSError(::bind(os_handle, (struct sockaddr*)&sip, sizeof(sip)))) {
int size = sizeof(sip);
if (ConvertOSError(::getsockname(os_handle, (struct sockaddr*)&sip, &size))) {
port = Net2Host(sip.sa_socket);
return TRUE;
}
}
}
os_close();
return FALSE;
}
BOOL PIPXSocket::ReadFrom(void * buf, PINDEX len, Address & addr, WORD & port)
{
lastReadCount = 0;
sockaddr_ipx sip;
int addrLen = sizeof(sip);
if (os_recvfrom(buf, len, 0, (struct sockaddr *)&sip, &addrLen)) {
AssignAddress(addr, sip);
port = Net2Host(sip.sa_socket);
}
return lastReadCount > 0;
}
BOOL PIPXSocket::WriteTo(const void * buf, PINDEX len, const Address & addr, WORD port)
{
lastWriteCount = 0;
sockaddr_ipx sip;
sip.sa_family = AF_IPX;
AssignAddress(sip, addr);
sip.sa_socket = Host2Net(port);
return os_sendto(buf, len, 0, (struct sockaddr *)&sip, sizeof(sip));
}
//////////////////////////////////////////////////////////////////////////////
// PSPXSocket
PSPXSocket::PSPXSocket(WORD port)
: PIPXSocket(port)
{
}
BOOL PSPXSocket::OpenSocket()
{
return ConvertOSError(os_handle = os_socket(AF_IPX, SOCK_STREAM, NSPROTO_SPX));
}
const char * PSPXSocket::GetProtocolName() const
{
return "spx";
}
BOOL PSPXSocket::Listen(unsigned queueSize, WORD newPort, Reusability reuse)
{
if (PIPXSocket::Listen(queueSize, newPort, reuse) &&
ConvertOSError(::listen(os_handle, queueSize)))
return TRUE;
os_close();
return FALSE;
}
BOOL PSPXSocket::Accept(PSocket & socket)
{
PAssert(socket.IsDescendant(PIPXSocket::Class()), "Invalid listener socket");
sockaddr_ipx sip;
sip.sa_family = AF_IPX;
int size = sizeof(sip);
if (!ConvertOSError(os_handle = os_accept(socket, (struct sockaddr *)&sip, &size)))
return FALSE;
port = ((PIPXSocket &)socket).GetPort();
return TRUE;
}
#endif
// End Of File ///////////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -