?? winsock.cxx
字號:
/*
* winsock.cxx
*
* WINSOCK implementation of Berkley sockets.
*
* Portable Windows Library
*
* Copyright (c) 1993-1998 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* $Log: winsock.cxx,v $
* Revision 1.71.4.1 2006/01/31 08:09:13 csoutheren
* Backported from CVS head
*
* Revision 1.73 2006/01/31 03:38:27 csoutheren
* Refixed fix for compiler warning
*
* Revision 1.72 2006/01/31 03:23:17 csoutheren
* Fixed compile warning on MSVC 6
*
* Revision 1.71 2005/11/30 12:47:42 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.70 2005/11/21 11:49:36 shorne
* Changed disableQos to disableGQoS to better reflect what it does
*
* Revision 1.69 2005/09/23 15:30:46 dominance
* more progress to make mingw compile nicely. Thanks goes to Julien Puydt for pointing out to me how to do it properly. ;)
*
* Revision 1.68 2005/09/18 13:01:44 dominance
* fixed pragma warnings when building with gcc.
*
* Revision 1.67 2005/08/08 06:59:39 rjongbloed
* Fixed compiler warning
*
* Revision 1.66 2005/07/13 12:08:09 csoutheren
* Fixed QoS patches to be more consistent with PWLib style and to allow Unix compatibility
*
* Revision 1.65 2005/07/13 11:48:55 csoutheren
* Backported QOS changes from isvo branch
*
* Revision 1.64 2004/10/23 10:45:32 ykiryanov
* Added ifdef _WIN32_WCE for PocketPC 2003 SDK port
*
* Revision 1.63 2004/05/06 11:28:30 rjongbloed
* Changed P_fd_set to use malloc/free isntead of new/delete due to pedantry about [].
*
* Revision 1.62 2004/04/27 09:53:27 rjongbloed
* Fixed ability to break of a PSocket::Select call under linux when a socket
* is closed by another thread.
*
* Revision 1.61 2004/04/03 08:22:22 csoutheren
* Remove pseudo-RTTI and replaced with real RTTI
*
* Revision 1.60 2003/11/12 04:40:58 csoutheren
* Fixed linking problem on systems without QoS or IPV6
*
* Revision 1.59 2003/11/10 00:21:38 dereksmithies
* Stop compiler warnings (unused formal parameters) when P_HAS_QOS is on
*
* Revision 1.58 2003/10/30 11:33:59 rjongbloed
* Added automatic inclusion of Winsock2 library.
*
* Revision 1.57 2003/10/28 23:36:22 csoutheren
* Changed to use ws2_32.lib or wsock32.lib depending on use of QoS
*
* Revision 1.56 2003/10/27 08:01:52 csoutheren
* Removed use of GetAddressByName when using Winsock2
*
* Revision 1.55 2003/10/27 03:29:11 csoutheren
* Added support for QoS
* Thanks to Henry Harrison of AliceStreet
*
* Revision 1.54 2003/09/17 05:45:10 csoutheren
* Removed recursive includes
*
* Revision 1.53 2002/10/29 08:00:16 robertj
* Changed in_addr6 to more universally used in6_addr.
*
* Revision 1.52 2002/10/19 06:12:20 robertj
* Moved P_fd_set::Zero() from platform independent to platform dependent
* code as Win32 implementation is completely different from Unix.
*
* Revision 1.51 2002/10/17 07:17:43 robertj
* Added ability to increase maximum file handles on a process.
*
* Revision 1.50 2002/10/08 12:41:52 robertj
* Changed for IPv6 support, thanks S閎astien Josset.
*
* Revision 1.49 2002/05/23 09:07:41 robertj
* Further adjustments to compensate for Winsock weirdness on some platforms.
*
* Revision 1.48 2002/05/23 01:54:35 robertj
* Worked around WinSock bug where getsockopt() does not work immediately
* after the select() function returns an exception.
*
* Revision 1.47 2002/05/22 07:22:17 robertj
* Fixed bug in waiting for connect with a timeout not checking for errors via
* the except fdset in the select() call. Would give timeout for all errors.
*
* Revision 1.46 2002/04/12 01:42:41 robertj
* Changed return value on os_connect() and os_accept() to make sure
* get the correct error codes propagated up under unix.
*
* Revision 1.45 2001/09/10 02:51:23 robertj
* Major change to fix problem with error codes being corrupted in a
* PChannel when have simultaneous reads and writes in threads.
*
* Revision 1.44 2001/09/06 02:30:31 robertj
* Fixed mismatched declarations, thanks Vjacheslav Andrejev
*
* Revision 1.43 2001/03/20 06:57:14 robertj
* os_accept() function changed due to unix changes re unblocking threads.
*
* Revision 1.42 2001/01/24 06:46:45 yurik
* Windows CE port-related changes
*
* Revision 1.41 1998/11/30 04:50:19 robertj
* New directory structure
*
* Revision 1.40 1998/11/14 06:31:15 robertj
* Changed semantics of os_sendto to return TRUE if ANY bytes are sent.
*
* Revision 1.39 1998/09/24 03:31:02 robertj
* Added open software license.
*
* Revision 1.38 1998/08/28 14:09:45 robertj
* Fixed bug in Write() that caused endlesss loops, introduced in previous version.
*
* Revision 1.37 1998/08/21 05:27:31 robertj
* Fixed bug where write streams out to non-stream socket.
*
* Revision 1.36 1998/08/06 00:55:21 robertj
* Fixed conversion of text to IPX address, was swapping nibbles.
*
* Revision 1.35 1998/05/08 11:52:03 robertj
* Added workaround for winsock bug where getpeername() doesn't work immediately after connect().
*
* Revision 1.34 1998/05/07 05:21:04 robertj
* Fixed DNS lookup so only works around bug in old Win95 and not OSR2
*
* Revision 1.33 1998/01/26 01:00:06 robertj
* Added timeout to os_connect().
* Fixed problems with NT version of IsLocalHost().
*
* Revision 1.32 1997/12/18 05:05:27 robertj
* Moved IsLocalHost() to platform dependent code.
*
* Revision 1.31 1997/12/11 10:41:55 robertj
* Added DWORD operator for IP addresses.
*
* Revision 1.30 1997/01/03 04:37:11 robertj
* Fixed '95 problem with send timeouts.
*
* Revision 1.29 1996/12/05 11:51:50 craigs
* Fixed Win95 recvfrom timeout problem
*
* Revision 1.28 1996/11/10 21:04:56 robertj
* Fixed bug in not flushing stream on close of socket.
*
* Revision 1.27 1996/10/31 12:39:30 robertj
* Fixed bug in byte order of port numbers in IPX protocol.
*
* Revision 1.26 1996/10/26 01:43:18 robertj
* Removed translation of IP address to host order DWORD. Is ALWAYS net order.
*
* Revision 1.25 1996/10/08 13:03:09 robertj
* More IPX support.
*
* Revision 1.24 1996/09/14 13:09:47 robertj
* Major upgrade:
* rearranged sockets to help support IPX.
* added indirect channel class and moved all protocols to descend from it,
* separating the protocol from the low level byte transport.
*
* Revision 1.23 1996/08/08 10:06:07 robertj
* Fixed incorrect value in write, causes incorrect output if send is split.
*
* Revision 1.22 1996/07/27 04:03:29 robertj
* Created static version of ConvertOSError().
*
* Revision 1.21 1996/06/01 04:19:34 robertj
* Added flush to PSocket destructor as needs to use Write() at that level.
*
* Revision 1.20 1996/05/15 10:23:08 robertj
* Changed millisecond access functions to get 64 bit integer.
* Added timeout to accept function.
* Added ICMP protocol socket, getting common ancestor to UDP.
*
* Revision 1.19 1996/04/29 12:22:26 robertj
* Fixed detection of infinite timeout.
*
* Revision 1.18 1996/04/17 12:09:52 robertj
* Fixed bug in detecting infinte timeout.
*
* Revision 1.17 1996/04/12 09:45:06 robertj
* Rewrite of PSocket::Read() to avoid "Connection Reset" errors caused by SO_RCVTIMEO
*
* Revision 1.17 1996/04/10 12:15:11 robertj
* Rewrite of PSocket::Read() to avoid "Connection Reset" errors caused by SO_RCVTIMEO.
*
* Revision 1.16 1996/04/05 01:42:28 robertj
* Assured PSocket::Write always writes the number of bytes specified.
*
* Revision 1.15 1996/03/31 09:11:06 robertj
* Fixed major performance problem in timeout read/write to sockets.
*
* Revision 1.14 1996/03/10 13:16:25 robertj
* Fixed ioctl of closed socket.
*
* Revision 1.13 1996/03/04 12:41:02 robertj
* Fixed bug in leaving socket in non-blocking mode.
* Changed _Close to os_close to be consistent.
*
* Revision 1.12 1996/02/25 11:23:40 robertj
* Fixed bug in Read for when a timeout occurs on select, not returning error code.
*
* Revision 1.11 1996/02/25 03:13:12 robertj
* Moved some socket functions to platform dependent code.
*
* Revision 1.10 1996/02/19 13:52:39 robertj
* Added SO_LINGER option to socket to stop data loss on close.
* Fixed error reporting for winsock classes.
*
* Revision 1.9 1996/02/15 14:53:36 robertj
* Added Select() function to PSocket.
*
* Revision 1.8 1996/01/23 13:25:48 robertj
* Moved Accept from platform independent code.
*
* Revision 1.7 1996/01/02 12:57:17 robertj
* Unix compatibility.
*
* Revision 1.6 1995/12/10 12:06:00 robertj
* Numerous fixes for sockets.
*
* Revision 1.5 1995/06/17 00:59:49 robertj
* Fixed bug with stream being flushed on read/write.
*
* Revision 1.4 1995/06/04 12:49:51 robertj
* Fixed bugs in socket read and write function return status.
* Fixed bug in socket close setting object state to "closed".
*
* Revision 1.3 1995/03/12 05:00:10 robertj
* Re-organisation of DOS/WIN16 and WIN32 platforms to maximise common code.
* Used built-in equate for WIN32 API (_WIN32).
*
* Revision 1.2 1995/01/03 09:43:27 robertj
* Moved out of band stuff to common.
*
* Revision 1.1 1994/10/30 12:06:56 robertj
* Initial revision
*/
#include <ptlib.h>
#include <ptlib/sockets.h>
#include <nspapi.h>
#include <svcguid.h>
#include <wsipx.h>
#ifdef _MSC_VER
#include <wsnwlink.h>
#else
#define IPX_PTYPE 0x4000
#define NS_DEFAULT 0
#define SVCID_NETWARE(_SapId) {(0x000B << 16)|(_SapId),0,0,{0xC0,0,0,0,0,0,0,0x46}}
#define SVCID_FILE_SERVER SVCID_NETWARE(0x4)
#endif
#if defined(P_WINSOCK2_LIBRARY)
#ifdef _MSC_VER
#pragma comment(lib, P_WINSOCK2_LIBRARY)
#endif
#else
#ifndef _WIN32_WCE
#ifdef _MSC_VER
#pragma comment(lib, "wsock32.lib")
#endif
#endif // !_WIN32_WCE
#endif
//////////////////////////////////////////////////////////////////////////////
// PWinSock
PWinSock::PWinSock()
{
WSADATA winsock;
#if 0 // old WinSock version check
PAssert(WSAStartup(0x101, &winsock) == 0, POperatingSystemError);
PAssert(LOBYTE(winsock.wVersion) == 1 &&
HIBYTE(winsock.wVersion) == 1, POperatingSystemError);
#endif
// ensure we support QoS
PAssert(WSAStartup(0x0202, &winsock) == 0, POperatingSystemError);
PAssert(LOBYTE(winsock.wVersion) >= 1 &&
HIBYTE(winsock.wVersion) >= 1, POperatingSystemError);
}
PWinSock::~PWinSock()
{
WSACleanup();
}
BOOL PWinSock::OpenSocket()
{
return FALSE;
}
const char * PWinSock::GetProtocolName() const
{
return NULL;
}
//////////////////////////////////////////////////////////////////////////////
// P_fd_set
void P_fd_set::Construct()
{
max_fd = UINT_MAX;
set = (fd_set *)malloc(sizeof(fd_set));
}
void P_fd_set::Zero()
{
if (PAssertNULL(set) != NULL)
FD_ZERO(set);
}
//////////////////////////////////////////////////////////////////////////////
// PSocket
PSocket::~PSocket()
{
Close();
}
BOOL PSocket::Read(void * buf, PINDEX len)
{
flush();
lastReadCount = 0;
if (len == 0)
return SetErrorValues(BadParameter, EINVAL, LastReadError);
os_recvfrom((char *)buf, len, 0, NULL, NULL);
return lastReadCount > 0;
}
BOOL PSocket::Write(const void * buf, PINDEX len)
{
flush();
return os_sendto(buf, len, 0, NULL, 0) && lastWriteCount >= len;
}
BOOL PSocket::Close()
{
if (!IsOpen())
return FALSE;
flush();
return ConvertOSError(os_close());
}
int PSocket::os_close()
{
int err = closesocket(os_handle);
os_handle = -1;
return err;
}
int PSocket::os_socket(int af, int type, int proto)
{
return ::socket(af, type, proto);
}
BOOL PSocket::os_connect(struct sockaddr * addr, PINDEX size)
{
if (readTimeout == PMaxTimeInterval)
return ConvertOSError(::connect(os_handle, addr, size));
DWORD fionbio = 1;
if (!ConvertOSError(::ioctlsocket(os_handle, FIONBIO, &fionbio)))
return FALSE;
fionbio = 0;
if (::connect(os_handle, addr, size) != SOCKET_ERROR)
return ConvertOSError(::ioctlsocket(os_handle, FIONBIO, &fionbio));
DWORD err = GetLastError();
if (err != WSAEWOULDBLOCK) {
::ioctlsocket(os_handle, FIONBIO, &fionbio);
SetLastError(err);
return ConvertOSError(-1);
}
P_fd_set writefds = os_handle;
P_fd_set exceptfds = os_handle;
P_timeval tv;
/* To avoid some strange behaviour on various windows platforms, do a zero
timeout select first to pick up errors. Then do real timeout. */
int selerr = ::select(1, NULL, writefds, exceptfds, tv);
if (selerr == 0) {
writefds = os_handle;
exceptfds = os_handle;
tv = readTimeout;
selerr = ::select(1, NULL, writefds, exceptfds, tv);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -