📄 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.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 + -