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

📄 listensocket.h

📁 WOW 服务模拟端 支持2.4.3版本 来自开源的ASCENT 自己REPACK
💻 H
字号:
/****************************************************************************
 *
 * Multiplatform High-Performance Async Network Library
 * Listen Socket Class
 * Copyright (c) 2007 Burlex
 *
 * This file may be distributed under the terms of the Q Public License
 * as defined by Trolltech ASA of Norway and appearing in the file
 * COPYING included in the packaging of this file.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#ifndef _NETLIB_LISTENSOCKET_H
#define _NETLIB_LISTENSOCKET_H

#ifndef NETLIB_IOCP

/** Standard ListenSocket
 */

template<class T>
class ListenSocket : public BaseSocket
{
	int new_fd;
	sockaddr_in new_peer;
	sockaddr_in address;
public:

	ListenSocket()
	{
		m_fd = socket(AF_INET, SOCK_STREAM, 0);
		u_long arg = 1;
		setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
		if(m_fd < 0)
		{
			printf("WARNING: ListenSocket constructor: could not create socket() %u (%s)\n", errno, strerror(errno));
		}
		m_connected = false;
		m_deleted = false;
	}

	void OnRead(size_t len)
	{
		if(!m_connected)
			return;

#ifdef WIN32
		int len2 = sizeof(sockaddr_in);
#else
		socklen_t len2 = sizeof(sockaddr_in);
#endif
		new_fd = accept(m_fd, (sockaddr*)&new_peer, &len2);
		if(new_fd > 0)
		{
			T * s = new T(new_fd, &new_peer);
			s->Finalize();
		}
	}

	void OnWrite(size_t len) {}
	void OnError(int err) {}
	void OnAccept(void * pointer) {}
	
	bool Open(const char * hostname, u_short port)
	{
		if(m_fd < 0)
		{
			printf("No fd in listensocket\n");
			return false;
		}

		if(!strcmp(hostname, "0.0.0.0"))
			address.sin_addr.s_addr = htonl(INADDR_ANY);
		else
		{
			hostent * h = gethostbyname(hostname);
			if(!h)
			{
				printf("Could not resolve listen address\n");
				return false;
			}

			memcpy(&address.sin_addr, h->h_addr_list[0], sizeof(in_addr));
		}

		address.sin_family = AF_INET;
		address.sin_port = ntohs(port);

		if(bind(m_fd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
		{
			printf("Could not bind\n");
			return false;
		}

		if(listen(m_fd, 5) < 0)
		{
			printf("Could not bind\n");
			return false;
		}

		// add to mgr
		m_connected = true;
		sSocketEngine.AddSocket(this);
		return true;
	}

	bool Writable() { return false; }

	void Delete()
	{
		if(m_deleted) return;
		m_deleted = true;
		
		/* queue deletion */
		sSocketDeleter.Add(this);

		if(m_connected) Disconnect();
	}

	void Disconnect()
	{
		if(!m_connected) return;
		m_connected = false;

		sSocketEngine.RemoveSocket(this);
		closesocket(m_fd);
		if(!m_deleted) Delete();
	}
};

#else

/** IOCP ListenSocket
 */

#include <mswsock.h>

template<class T>
class ListenSocket : public BaseSocket
{
	int new_fd;
	sockaddr_in new_peer;
	sockaddr_in address;
public:

	ListenSocket()
	{
		//m_fd = socket(AF_INET, SOCK_STREAM, 0);
		m_fd = WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);
		m_connected = false;
		m_deleted = false;
	}

	void OnRead(size_t len) { }
	void OnWrite(size_t len) {}
	void OnError(int err) {}

	void OnAccept(void * pointer)
	{
		int fd = *(int*)pointer;

		/* no idea if this will work on x64 :P */
		sockaddr_in * addr = (sockaddr_in*)&((char*)pointer)[42];
		T * s = new T(fd, addr);
		s->Finalize();
		free(pointer);
		
		/* post the next accept event */
		PostEvent();
	}

	bool Writable() { return false; }

	void Delete()
	{
		if(m_deleted) return;
		m_deleted = true;

		/* queue deletion */
		sSocketDeleter.Add(this);

		if(m_connected) Disconnect();
	}

	void Disconnect()
	{
		if(!m_connected) return;
		m_connected = false;

		sSocketEngine.RemoveSocket(this);
		closesocket(m_fd);
		if(!m_deleted) Delete();
	}

	void PostEvent()
	{
		Overlapped * ov = new Overlapped;
		memset(ov, 0, sizeof(Overlapped));
		ov->m_op = IO_EVENT_ACCEPT;
		ov->m_acceptBuffer = malloc(1024);
		memset(ov->m_acceptBuffer, 0, 1024);
		/*int s = socket(AF_INET, SOCK_STREAM, 0);*/
		int s = WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);
		int len = sizeof(sockaddr_in) + 16;
		*(int*)&((char*)ov->m_acceptBuffer)[0] = s;
		DWORD bytes;

		if(!AcceptEx(m_fd, s, ((char*)ov->m_acceptBuffer) + sizeof(int), 0, len, len, &bytes, &ov->m_ov))
		{
			if(WSA_IO_PENDING != WSAGetLastError())
				printf("AcceptEx error: %u\n", WSAGetLastError());
		}
	}

	bool Open(const char * hostname, u_short port)
	{
		if(m_fd < 0)
			return false;

		if(!strcmp(hostname, "0.0.0.0"))
			address.sin_addr.s_addr = htonl(INADDR_ANY);
		else
		{
			hostent * h = gethostbyname(hostname);
			if(!h)
				return false;

			memcpy(&address.sin_addr, h->h_addr_list[0], sizeof(in_addr));
		}

		address.sin_family = AF_INET;
		address.sin_port = ntohs(port);

		if(bind(m_fd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
			return false;

		if(listen(m_fd, 5) < 0)
			return false;

		m_connected = true;
		sSocketEngine.AddSocket(this);
		PostEvent();
		return true;
	}
};

#endif		// NETLIB_IOCP

/* Common Functions */
template<class T>
bool CreateListenSocket(const char * hostname, u_short port)
{
	ListenSocket<T> * s = new ListenSocket<T>();
	if(!s->Open(hostname, port))
	{
		s->Delete();
		return false;
	}
	else
		return true;
}

#endif		// _NETLIB_LISTENSOCKET_H

⌨️ 快捷键说明

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