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

📄 vsocket.cpp

📁 teamviewer source code vc++
💻 CPP
字号:
//  Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
//
//  This file is part of TeamViewer.
//
//  TeamViewer is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//
//  If the source code for TeamViewer is not available from the place 
//  whence you received this file, check http://www.teamviewer.com
//  for information on obtaining it.


// VSocket.cpp

// The VSocket class provides a platform-independent socket abstraction
// with the simple functionality required for an RFB server.


////////////////////////////////////////////////////////
// System includes

#include "stdhdrs.h"

////////////////////////////////////////////////////////
// Custom includes

#include "VTypes.h"

#define EWOULDBLOCK WSAEWOULDBLOCK

extern bool isQuickSupport;

////////////////////////////////////////////////////////
// Socket implementation
class VSocket;

#include "VSocket.h"

// The socket timeout value (currently 5 seconds, for no reason...)
// *** THIS IS NOT CURRENTLY USED ANYWHERE
const VInt rfbMaxClientWait = 5000;

////////////////////////////
// Socket implementation initialisation

static WORD winsockVersion = 0;

VSocketSystem::VSocketSystem()
{
  // Initialise the socket subsystem
  // This is only provided for compatibility with Windows.

  // Initialise WinPoxySockets on Win32
  WORD wVersionRequested;
  WSADATA wsaData;
	
  wVersionRequested = MAKEWORD(2, 0);
  if (WSAStartup(wVersionRequested, &wsaData) != 0)
  {
    m_status = VFalse;
	return;
  }

  winsockVersion = wsaData.wVersion;
 
  // If successful, or if not required, then continue!
  m_status = VTrue;
}

VSocketSystem::~VSocketSystem()
{
	if (m_status)
	{
		WSACleanup();
	}
}

////////////////////////////

VSocket::VSocket()
{
	// Clear out the internal socket fields
	sock = -1;
	
	m_pNetRectBuf = NULL;
	m_nNetRectBufSize = 0;
	m_fWriteToNetRectBuf = false;
	m_nNetRectBufOffset = 0;
	queuebuffersize=0;
	m_BytesRead = 0;
	m_BytesSent = 0;
}

////////////////////////////

VSocket::~VSocket()
{
  // Close the socket
  Close();

  if (m_pNetRectBuf != NULL)
 	delete [] m_pNetRectBuf;

}

////////////////////////////

VBool
VSocket::Create()
{
  const int one = 1;

  // Check that the old socket was closed
  if (sock >= 0)
    Close();

  // Create the socket
  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
      return VFalse;
    }

  // Set the socket options:
//#ifndef WIN32
  if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, sizeof(one)))
    {
      return VFalse;
    }
//#endif
  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)))
	{
	  return VFalse;
	}

  return VTrue;
}

////////////////////////////

VBool
VSocket::Close()
{
	omni_mutex_lock l(m_close_lock);
	if (sock >= 0)
	{
		vnclog.Print(LL_SOCKINFO, VNCLOG("closing socket"));

		shutdown(sock, SD_BOTH);
		if(GetLastError() == WSAENOTCONN)
			SetLastError(0);					// ignore "socket not connected" error message

		closesocket(sock);
		sock = -1;
	}
	return VTrue;
}

////////////////////////////

VBool
VSocket::Shutdown()
{
  if (sock >= 0)
    {
	  vnclog.Print(LL_SOCKINFO, VNCLOG("shutdown socket"));

	  shutdown(sock, SD_BOTH);
	  if(GetLastError() == WSAENOTCONN)
		  SetLastError(0);					// ignore "socket not connected" error message
    }
  return VTrue;
}

////////////////////////////

VBool
VSocket::Bind(const VCard port, const VBool localOnly)
{
  struct sockaddr_in addr;

  // Check that the socket is open!
  if (sock < 0)
    return VFalse;

  // Set up the address to bind the socket to
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
#ifdef _DEBUG
  if (localOnly)  // QuickSupport-Tool only listens to localhost
#else
  if (localOnly || isQuickSupport)  // QuickSupport-Tool only listens to localhost
#endif
	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  else
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

  // And do the binding
  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
      return VFalse;

  return VTrue;
}

////////////////////////////

VBool
VSocket::Connect(const VString address, const VCard port)
{
  // Check the socket
  if (sock < 0)
    return VFalse;

  // Create an address structure and clear it
  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));

  // Fill in the address if possible
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_addr(address);

  // Was the string a valid IP address?
  if (addr.sin_addr.s_addr == -1)
    {
      // No, so get the actual IP address of the host name specified
      struct hostent *pHost;
      pHost = gethostbyname(address);
      if (pHost != NULL)
	  {
		  if (pHost->h_addr == NULL)
			  return VFalse;
		  addr.sin_addr.s_addr = ((struct in_addr *)pHost->h_addr)->s_addr;
	  }
	  else
	    return VFalse;
    }

  // Set the port number in the correct format
  addr.sin_port = htons(port);

  // Actually connect the socket
  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
	  return VTrue;

  SetLastError(0);					// we don't want the error message to be logged later
  return VFalse;
}

////////////////////////////
// neuer Connect-Aufruf f黵 躡ergabe des Client-Sockets an einen Server-VSocket

VBool
VSocket::Connect(SOCKET mysock)
{
  // Check socket
  if (mysock < 0)
    return VFalse;

	sock= mysock;

    return VTrue;
}

////////////////////////////

VBool
VSocket::Listen()
{
  // Check socket
  if (sock < 0)
    return VFalse;

	// Set it to listen
  if (listen(sock, 5) < 0)
    return VFalse;

  return VTrue;
}

////////////////////////////

VSocket *
VSocket::Accept()
{
  const int one = 1;

  int new_socket_id;
  VSocket * new_socket;

  // Check this socket
  if (sock < 0)
    return NULL;

  // Accept an incoming connection
  if ((new_socket_id = accept(sock, NULL, 0)) < 0)
  {
	  vnclog.Print(0, VNCLOG("accept %d"), new_socket_id);
	  return NULL;
  }

  // Create a new VSocket and return it
  new_socket = new VSocket;
  if (new_socket != NULL)
    {
      new_socket->sock = new_socket_id;
	  // Attempt to set the new socket's options
	  setsockopt(new_socket->sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));
    }
  else
    {
	  shutdown(new_socket_id, SD_BOTH);
	  closesocket(new_socket_id);
    }

  return new_socket;
}

////////////////////////////

VString
VSocket::GetPeerName()
{
	struct sockaddr_in	sockinfo;
	struct in_addr		address;
	int					sockinfosize = sizeof(sockinfo);
	VString				name;

	// Get the peer address for the client socket
	getpeername(sock, (struct sockaddr *)&sockinfo, &sockinfosize);
	memcpy(&address, &sockinfo.sin_addr, sizeof(address));

	name = inet_ntoa(address);
	if (name == NULL)
		return "<unavailable>";
	else
		return name;
}

////////////////////////////

VString
VSocket::GetSockName()
{
	struct sockaddr_in	sockinfo;
	struct in_addr		address;
	int					sockinfosize = sizeof(sockinfo);
	VString				name;

	// Get the peer address for the client socket
	getsockname(sock, (struct sockaddr *)&sockinfo, &sockinfosize);
	memcpy(&address, &sockinfo.sin_addr, sizeof(address));

	name = inet_ntoa(address);
	if (name == NULL)
		return "<unavailable>";
	else
		return name;
}

////////////////////////////

VCard32
VSocket::Resolve(const VString address)
{
  VCard32 addr;

  // Try converting the address as IP
  addr = inet_addr(address);

  // Was it a valid IP address?
  if (addr == 0xffffffff)
    {
      // No, so get the actual IP address of the host name specified
      struct hostent *pHost;
      pHost = gethostbyname(address);
      if (pHost != NULL)
	  {
		  if (pHost->h_addr == NULL)
			  return 0;
		  addr = ((struct in_addr *)pHost->h_addr)->s_addr;
	  }
	  else
		  return 0;
    }

  // Return the resolved IP address as an integer
  return addr;
}

////////////////////////////

VBool
VSocket::SetTimeout(VCard32 msecs)
{
	if (LOBYTE(winsockVersion) < 2)
		return VFalse;
	int timeout=msecs;
	if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
	{
		return VFalse;
	}
	if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout)) == SOCKET_ERROR)
	{
		return VFalse;
	}
	return VTrue;
}

////////////////////////////
VInt
VSocket::Send(const char *buff, const VCard bufflen)
{
	int newsize=queuebuffersize+bufflen;
	char *buff2;
	buff2=(char*)buff;
	unsigned int bufflen2=bufflen;
    m_BytesSent += bufflen;
	if (newsize >8192)
	{
		    memcpy(queuebuffer+queuebuffersize,buff2,8192-queuebuffersize);
			send(sock,queuebuffer,8192,0);
//			vnclog.Print(LL_SOCKERR, VNCLOG("SEND  %i") ,8192);
			buff2+=(8192-queuebuffersize);
			bufflen2-=(8192-queuebuffersize);
			queuebuffersize=0;
			while (bufflen2 > 8192)
			{
				if (!send(sock,buff2,8192,0)) return false;
//				vnclog.Print(LL_SOCKERR, VNCLOG("SEND 1 %i") ,8192);
				buff2+=8192;
				bufflen2-=8192;
			}
	}
	memcpy(queuebuffer+queuebuffersize,buff2,bufflen2);
	queuebuffersize+=bufflen2;
	if (!send(sock,queuebuffer,queuebuffersize,0)) return false;
//	vnclog.Print(LL_SOCKERR, VNCLOG("SEND 2 %i") ,queuebuffersize);
	queuebuffersize=0;
	return bufflen;
}
////////////////////////////
VInt
VSocket::SendQueued(const char *buff, const VCard bufflen)
{
	int newsize=queuebuffersize+bufflen;
	char *buff2;
	buff2=(char*)buff;
	unsigned int bufflen2=bufflen;
	m_BytesSent += bufflen;	
	if (newsize >8192)
	{
		    memcpy(queuebuffer+queuebuffersize,buff2,8192-queuebuffersize);
			send(sock,queuebuffer,8192,0);
		//	vnclog.Print(LL_SOCKERR, VNCLOG("SEND Q  %i") ,8192);
			buff2+=(8192-queuebuffersize);
			bufflen2-=(8192-queuebuffersize);
			queuebuffersize=0;
			while (bufflen2 > 8192)
			{
				if (!send(sock,buff2,8192,0)) return false;
			//	vnclog.Print(LL_SOCKERR, VNCLOG("SEND Q  %i") ,8192);
				buff2+=8192;
				bufflen2-=8192;
			}
	}
	memcpy(queuebuffer+queuebuffersize,buff2,bufflen2);
	queuebuffersize+=bufflen2;
	return bufflen;
}
/////////////////////////////

// sf@2002 - DSMPlugin
VBool
VSocket::SendExact(const char *buff, const VCard bufflen, unsigned char msgType)
{
	//vnclog.Print(LL_SOCKERR, VNCLOG("SendExactMsg %i") ,bufflen);
	return SendExact(buff, bufflen);
}

//////////////////////////////////////////
VBool
VSocket::SendExact(const char *buff, const VCard bufflen)
{
//	vnclog.Print(LL_SOCKERR, VNCLOG("SendExact %i") ,bufflen);
	// sf@2002 - DSMPlugin
	VCard nBufflen = bufflen;
	char* pBuffer = NULL;
	pBuffer = (char*) buff;
	
	VInt result=Send(pBuffer, nBufflen);
    return result == (VInt)nBufflen;
}
///////////////////////////////////////
VBool
VSocket::SendExactQueue(const char *buff, const VCard bufflen)
{
//	vnclog.Print(LL_SOCKERR, VNCLOG("SendExactQueue %i %i") ,bufflen,queuebuffersize);
//	vnclog.Print(LL_SOCKERR, VNCLOG("socket size %i") ,bufflen);
	// sf@2002 - DSMPlugin
	VCard nBufflen = bufflen;
	char* pBuffer = NULL;
	pBuffer = (char*) buff;
	
	VInt result=SendQueued(pBuffer, nBufflen);
  return result == (VInt)nBufflen;
}
///////////////////////////////
void
VSocket::ClearQueue()
{
	if (queuebuffersize!=0)
  {
	send(sock,queuebuffer,queuebuffersize,0);
	queuebuffersize=0;
  }
}
////////////////////////////

VInt
VSocket::Read(char *buff, const VCard bufflen)
{
  m_BytesRead += bufflen;
  return recv(sock, buff, bufflen, 0);
}

////////////////////////////

VBool
VSocket::ReadExact(char *buff, const VCard bufflen)
{
	int n;
	VCard currlen = bufflen;
    
	while (currlen > 0)
	{
		// Try to read some data in
		n = Read(buff, currlen);
		
		if (n > 0)
		{
			// Adjust the buffer position and size
			buff += n;
			currlen -= n;
		} else if (n == 0) {
			vnclog.Print(LL_SOCKERR, VNCLOG("zero bytes read2"));
			
			return VFalse;
		} else {
			if (WSAGetLastError() != WSAEWOULDBLOCK)
			{
				int aa=WSAGetLastError();
				vnclog.Print(LL_SOCKERR, VNCLOG("socket error 2: %d"), aa);
				return VFalse;
			}
		}
	}
	return VTrue;
}


//
// sf@2002 - DSMPlugin
// 

//
// Ensures that the temporary "alignement" buffer in large enough 
//
void VSocket::CheckNetRectBufferSize(int nBufSize)
{
    omni_mutex_lock l(m_CheckMutex); 

	if (m_nNetRectBufSize > nBufSize) return;

	BYTE *newbuf = new BYTE[nBufSize + 256];
	if (newbuf == NULL) 
	{
		// throw ErrorException("Insufficient memory to allocate network crypt buffer.");
	}

	if (m_pNetRectBuf != NULL)
	{
		// memcpy(newbuf, m_pNetRectBuf, m_nNetRectBufSize);
		delete [] m_pNetRectBuf;
	}

	m_pNetRectBuf = newbuf;
	m_nNetRectBufSize = nBufSize + 256;
	// vnclog.Print(4, VNCLOG(_T("crypt bufsize expanded to %d")), m_netbufsize);
}


// sf@2002 - DSMPlugin
// Necessary for HTTP server (we'll see later if we can do something more intelligent...

VBool
VSocket::SendExactHTTP(const char *buff, const VCard bufflen)
{
  return Send(buff, bufflen) == (VInt)bufflen;
}


////////////////////////////

VBool
VSocket::ReadExactHTTP(char *buff, const VCard bufflen)
{
	int n;
	VCard currlen = bufflen;
    
	while (currlen > 0)
	{
		// Try to read some data in
		n = Read(buff, currlen);

		if (n > 0)
		{
			// Adjust the buffer position and size
			buff += n;
			currlen -= n;
		} else if (n == 0) {
			vnclog.Print(LL_SOCKERR, VNCLOG("zero bytes read3"));

			return VFalse;
		} else {
			if (WSAGetLastError() != WSAEWOULDBLOCK)
			{
				vnclog.Print(LL_SOCKERR, VNCLOG("HTTP socket error: %d"), WSAGetLastError());
				return VFalse;
			}
		}
    }

	return VTrue;
}
#ifdef HTTP_SAMEPORT
VBool
VSocket::ReadSelect(VCard to)
 {
 	fd_set fds;
 	FD_ZERO(&fds);
 	FD_SET((unsigned long)sock,&fds);
	struct timeval tv;
 	tv.tv_sec = to/1000;
 	tv.tv_usec = (to % 1000)*1000;
 	int rc = select(sock+1,&fds,0,0,&tv);
 	if (rc>0) return true;
 	return false;
 }
#endif




⌨️ 快捷键说明

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