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

📄 cnvsocket.cpp

📁 这是一个远程控制程序
💻 CPP
字号:
//---------------------------------------------------------------------------

#pragma hdrstop

#include "CNVSocket.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

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

class VSocket;

////////////////////////////////////////////////////////
// System includes
#include <iostream.h>

#include <stdio.h>
#include <io.h>
#include <winsock2.h>
#include <sys/types.h>

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

#include "CNVTypes.h"

////////////////////////////////////////////////////////
// *** Lovely hacks to make Win32 work.  Hurrah!
#define EWOULDBLOCK WSAEWOULDBLOCK
////////////////////////////////////////////////////////
// Socket implementation

#include "CNVSocket.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;
}

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

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

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

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:
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)))
        {
                return VFalse;
        }
        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)))
        {
                return VFalse;
        }

        return VTrue;
}

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

VBool VSocket::Close()
{
        if (sock >= 0)
        {
	        shutdown(sock, SD_BOTH);
	        closesocket(sock);
                sock = -1;
        }
        return VTrue;
}

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

VBool VSocket::Shutdown()
{
        if (sock >= 0)
        {
	        shutdown(sock, SD_BOTH);
        }
        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;

        // If a specific port is being set then check it's not already used!
        if (port != 0)
        {
                VSocket dummy;

                if (dummy.Create())
                {
                        // If we're able to connect then the port number is in use...
                         if (dummy.Connect("localhost", port))
                                return VFalse;
                }
        }

        // Set up the address to bind the socket to
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        if (localOnly)
                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;

        return VFalse;
}

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

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)
                return NULL;

        // Create a new VSocket and return it
        new_socket = new VSocket;
        if (new_socket != NULL)
        {
                new_socket->sock = new_socket_id;
        }
        else
        {
                shutdown(new_socket_id, SD_BOTH);
                closesocket(new_socket_id);
        }

        // Attempt to set the new socket's options
        setsockopt(new_socket->sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one));

        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 secs)
{
	if (LOBYTE(winsockVersion) < 2)
		return VFalse;
	int timeout=secs;
	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)
{
        VInt SentBytes = 0;
        VInt AmountSent= 0;
        VInt AmountInBuf = bufflen;
        
        while( AmountInBuf > 0)
        {
                SentBytes = send(sock, buff, AmountInBuf, 0);

                AmountInBuf -= SentBytes;
                AmountSent  += SentBytes;

                buff += SentBytes;
        }
        return AmountSent;
}


VInt VSocket::SendText(TCNString Text)
{
        if( !Text.IsEmpty())
        {
                return Send(Text.c_str(),Text.Length());
        }
        else
        {
                return 0;
        }
}

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

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

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

VInt VSocket::Read(char *buff, const VCard 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) {
			return VFalse;
		} else {
			if (errno != EWOULDBLOCK)
			{
				return VFalse;
			}
		}
        }
	return VTrue;
}
VBool VSocket::SendStream(TCNStream *Stream)
{
        char Buffer[4096];

        int AmountInBuf;
        int AmountSent;
        int StartPos;

        if( Stream == NULL) return FALSE;

        while( TRUE)
        {
                StartPos = Stream->GetPosition();
                AmountInBuf = Stream->Read(Buffer,sizeof(Buffer));
                if( AmountInBuf > 0)
                {
                        AmountSent = Send(Buffer,AmountInBuf);
                        if( AmountSent == SOCKET_ERROR)
                        {
                                Stream->SetPosition(StartPos);
                                return FALSE;
                        }
                        else if(AmountInBuf > AmountSent)
                        {
                                Stream->SetPosition(StartPos + AmountSent);
                        }
                        else if( Stream->GetPosition() == Stream->GetSize())
                        {
                                break;
                        }
                }
        }
        return TRUE;
}

⌨️ 快捷键说明

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