⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winsock.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/* * 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.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>#include <wsnwlink.h>#if defined(P_WINSOCK2_LIBRARY)#pragma comment(lib, P_WINSOCK2_LIBRARY)#else#ifndef _WIN32_WCE#pragma comment(lib, "wsock32.lib")#endif // !_WIN32_WCE#endif//////////////////////////////////////////////////////////////////////////////// PWinSockPWinSock::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_setvoid 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);}//////////////////////////////////////////////////////////////////////////////// PSocketPSocket::~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);  }  switch (selerr) {    case 1 :      if (writefds.IsPresent(os_handle)) {        // The following is to avoid a bug in Win32 sockets. The getpeername() function doesn't        // work for some period of time after a connect, saying it is not connected yet!        for (PINDEX failsafe = 0; failsafe < 1000; failsafe++) {          sockaddr_in address;          int sz = sizeof(address);          if (::getpeername(os_handle, (struct sockaddr *)&address, &sz) == 0) {            if (address.sin_port != 0)              break;          }          ::Sleep(0);        }        err = 0;      }      else {        // The following is to avoid a bug in Win32 sockets. The getsockopt() function        // doesn't work for some period of time after a connect, saying no error!

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -