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