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

📄 transporttcpipserver.cpp

📁 .net 方面的开发说明资料。
💻 CPP
字号:
// ========================================================
// TCP/IP Transport (listening) implementation
//
// Design and Implementation by Floris van den Berg
// ========================================================

#pragma warning (disable : 4275)
#pragma warning (disable : 4786)

#include <winsock2.h>
#include <windows.h>
#include <process.h>

#include "Agent.h"
#include "OpenNet.h"
#include "EventDispatcher.h"
#include "TransportTCPIPServer.h"
#include "Utilities.h"

// --------------------------------------------------------

class CTransportTCPIPServer : public ITransport {
	friend int CALLBACK ConditionFunction(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQOS, LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR *g, DWORD dwCallbackData);

public :
	CTransportTCPIPServer();
	virtual ~CTransportTCPIPServer();

public :
	virtual bool DLL_CALLCONV Open(PROPERTYGROUP_HANDLE group);
	virtual void DLL_CALLCONV PassHandleIndirect(long handle);
	virtual void DLL_CALLCONV Close();
	virtual void DLL_CALLCONV Connect(const char *host, int port);
	virtual void DLL_CALLCONV Disconnect();
	virtual bool DLL_CALLCONV SupportsSending();
	virtual void DLL_CALLCONV Send(Action *action);
	virtual void* DLL_CALLCONV GetReferenceData(int id);
	virtual bool DLL_CALLCONV GetOption(int option, void *value, int *size);
	virtual bool DLL_CALLCONV SetOption(int option, void *value);
	virtual bool DLL_CALLCONV CanBeBalanced();
	virtual void DLL_CALLCONV PollProgress();
	virtual void DLL_CALLCONV IncActionCount();

private :
	boost::mutex m_cs;
	Action *m_action;
	SOCKET m_socket;
	HANDLE m_wait_event;
	sockaddr_in m_sockaddr_in;
	LONG m_action_count;
};

// --------------------------------------------------------

int CALLBACK
ConditionFunction(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQOS, LPQOS lpGQOS, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR *g, DWORD dwCallbackData) {
	return 0;
}

// --------------------------------------------------------

CTransportTCPIPServer::CTransportTCPIPServer() :
m_cs(),
m_action(NULL),
m_socket(NULL),
m_wait_event(),
m_sockaddr_in(),
m_action_count(0) {
	m_wait_event = WSACreateEvent();
}

CTransportTCPIPServer::~CTransportTCPIPServer() {
	WSACloseEvent(m_wait_event);
}

// --------------------------------------------------------
// Open/Close/Connect/Disconnect a Plug
// --------------------------------------------------------

bool DLL_CALLCONV
CTransportTCPIPServer::Open(PROPERTYGROUP_HANDLE group) {
	int port = 0;
	EpPropGetValueAsInt(group, "port", &port);

	if ((m_socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, NULL, WSA_FLAG_OVERLAPPED)) != INVALID_SOCKET) {
		if (WSAEventSelect(m_socket, m_wait_event, FD_CLOSE | FD_ACCEPT) == 0) {
			m_sockaddr_in.sin_family = PF_INET;
			m_sockaddr_in.sin_port = htons(port);
			m_sockaddr_in.sin_addr.s_addr = ADDR_ANY;

			if (bind(m_socket, (sockaddr *)&m_sockaddr_in, sizeof(m_sockaddr_in)) == 0)
				if (listen(m_socket, SOMAXCONN) == 0) {
					return true;
				}
		}
	}

	return false;
}

void DLL_CALLCONV
CTransportTCPIPServer::PassHandleIndirect(long handle) {
}

void DLL_CALLCONV
CTransportTCPIPServer::Close() {
	if (m_socket) {
		closesocket(m_socket);
	}
}

void DLL_CALLCONV
CTransportTCPIPServer::Connect(const char *host, int port) {
}

void DLL_CALLCONV
CTransportTCPIPServer::Disconnect() {
}

bool DLL_CALLCONV
CTransportTCPIPServer::SupportsSending() {
	return false;
}

void DLL_CALLCONV
CTransportTCPIPServer::Send(Action *action) {
}

void * DLL_CALLCONV
CTransportTCPIPServer::GetReferenceData(int id) {
	return NULL;
}

bool DLL_CALLCONV
CTransportTCPIPServer::GetOption(int option, void *value, int *size) {
	return false;
}

bool DLL_CALLCONV
CTransportTCPIPServer::SetOption(int option, void *value) {
	return false;
}

bool DLL_CALLCONV
CTransportTCPIPServer::CanBeBalanced() {
	return true;
}

void DLL_CALLCONV
CTransportTCPIPServer::PollProgress() {
	boost::mutex::scoped_lock scoped_lock(m_cs);

	// create an event to be passed to grid

	EpEvent pm_event;
	pm_event.reference_id = 0;
	pm_event.protocol = CLSID_SYSTEM_PROTOCOL;
	pm_event.msg = 0;
	pm_event.size = 0;
	pm_event.data = 0;

	// see if there are any incoming events

	WSANETWORKEVENTS ne;
	memset(&ne, 0, sizeof(ne));	

	if (WSAEnumNetworkEvents(m_socket, m_wait_event, &ne) == 0) {
		if ((ne.lNetworkEvents & FD_ACCEPT) == FD_ACCEPT) {
			if (ne.iErrorCode[FD_ACCEPT_BIT] != 0) {
				switch(ne.iErrorCode[FD_ACCEPT_BIT]) {
					case WSAENETDOWN :
						pm_event.msg = SYSTEM_TCPIP_SUBSYSTEM_FAILED;
						EpDispatchEvent(this, &pm_event);
						break;

					default :
						pm_event.msg = SYSTEM_TCPIP_UNIMPLEMENTED;
						pm_event.data = (unsigned char *)&ne.iErrorCode[FD_READ_BIT];
						pm_event.size = 4;

						EpDispatchEvent(this, &pm_event);

						pm_event.data = NULL;
						pm_event.size = 0;
						break;
				};

				pm_event.msg = SYSTEM_TCPIP_ACCEPT_FAILED;
				EpDispatchEvent(this, &pm_event);
			} else {
				sockaddr_in incoming_address;
				int incoming_address_len = sizeof(sockaddr_in);

				SOCKET m_accept_socket;

				if ((m_accept_socket = WSAAccept(m_socket, (sockaddr *)&incoming_address, &incoming_address_len, ConditionFunction, (unsigned long)this)) == SOCKET_ERROR) {
					switch(WSAGetLastError()) {
						case WSAECONNREFUSED :
							pm_event.msg = SYSTEM_TCPIP_CONNECTION_REFUSED;
							EpDispatchEvent(this, &pm_event);
							break;

						case WSAENETDOWN :
							pm_event.msg = SYSTEM_TCPIP_SUBSYSTEM_FAILED;
							EpDispatchEvent(this, &pm_event);
							break;

						case WSAENOBUFS :
							pm_event.msg = SYSTEM_TCPIP_NO_BUFFERSPACE;
							EpDispatchEvent(this, &pm_event);
							break;

						case WSATRY_AGAIN :
							pm_event.msg = SYSTEM_TCPIP_ACCEPT_TRY_AGAIN;
							EpDispatchEvent(this, &pm_event);
							break;

						case WSAEACCES :
							pm_event.msg = SYSTEM_TCPIP_ACCEPT_WITHDRAWN;
							EpDispatchEvent(this, &pm_event);
							break;
					};

					pm_event.msg = SYSTEM_TCPIP_ACCEPT_FAILED;
					EpDispatchEvent(this, &pm_event);
				} else {					
					char tmp[256];
					sprintf(tmp, "indirect type=tcp handle=%d", m_accept_socket);

					EpDispatchSystemEvent(this, SYSTEM_CONNECTION_REQUEST, (unsigned char *)tmp, strlen(tmp) + 1);
				}
			}
		}

		if ((ne.lNetworkEvents & FD_CLOSE) == FD_CLOSE) {
			m_action = NULL;
			m_action_count = 0;

			if (ne.iErrorCode[FD_CLOSE_BIT] != 0) {
				switch (ne.iErrorCode[FD_CLOSE_BIT]) {
					case WSAECONNRESET :
						pm_event.msg = SYSTEM_TCPIP_CONNECTION_RESET;
						EpDispatchEvent(this, &pm_event);
						break;

					case WSAECONNABORTED :
						pm_event.msg = SYSTEM_TCPIP_CONNECTION_ABORTED;
						EpDispatchEvent(this, &pm_event);
						break;

					default :
						pm_event.msg = SYSTEM_TCPIP_UNIMPLEMENTED;
						pm_event.data = (unsigned char *)&ne.iErrorCode[FD_CLOSE_BIT];
						pm_event.size = 4;

						EpDispatchEvent(this, &pm_event);

						pm_event.data = NULL;
						pm_event.size = 0;
						break;
				};
			}
		}
	}
}

void DLL_CALLCONV
CTransportTCPIPServer::IncActionCount() {
	boost::mutex::scoped_lock scoped_lock(m_cs);
	++m_action_count;
}

// --------------------------------------------------------
// Instantation function
// --------------------------------------------------------

HRESULT DLL_CALLCONV
TCPIPServerCreate(void **iif) {
	CTransportTCPIPServer *object = new CTransportTCPIPServer;

	if (object) {
		*iif = object;
		return S_OK;
	}

	return E_FAIL;
}

⌨️ 快捷键说明

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