77-Windows下原生API 用IOCP编写一个简易的服务器模型 1_recv

文章目录

    • 1.main.cpp
    • 2.server.cpp
    • 3.server.h

1.main.cpp

#include 
#include 
#include    //这个服务器是多线程版本
#include 
#include 
#include 
#include "Server.h"

#pragma comment(lib,"Ws2_32.lib")   //规定文件在编译的时候需要哪个lib
std::map<int, ServerSocket::Pointer> players;

void handlerRecvData(const ServerSocket::pointer& p,
	const char* data,
	int size) {
     
	std::string info(data, data + size);
	std::cout << "recv: " << info << std::endl;
	for (int i = 0;i < 10;++i)
	{
     
		Sleep(1);
		p->sendMessage("+hello world!");
	}
}

int main(int argc,char** argv)
{
     
	signal(SIGINT,signalHandler);
	WSADATA data;
	//window编程不考虑tcp
	//需要先加载一个动态库,目前最新是2.2
	auto result = WSAStartup(MAKEWORD(2, 2), &data);
	//0表示成功,01表示有错误
	if (result != NO_ERROR)
	{
     
		std::cout << "error at WSAStartup\n";
		return 1;
	}

	auto server = std::make_unique<Server>(8901);
	if (!server) {
     
		WSACleanup();
		return 1;
	}

	server->socketRecv = handleRecvData;
	server->socketClose = handleRemovePlayer;

	auto clientIo = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
	bool gameOver = false;
	std::thread updateClientIo(
		[clientIo, &gameOver] {
     updateClientIo(clientIo, gameOver);}
	);
	auto p = server.get();
	handler = [p] {
     p->stop();};















	//调用析构函数释放
	//但是是在main函数中不释放也没关系
	//每调用一次WSAStart时,都要调用一次WSACleanup()
	WSACleanup();
	return 0;

}

2.server.cpp

#include "Server.h"
#include 
#include 

Server::Server(u_short p)
	:m_port(p),
	//unix任何事物都是文件,window中任何事物都是handle
	m_listenSocket(INVALID_SOCKET),
	m_completePort(NULL),
	lpfnAcceptEx(nullptr),
	m_currentAccetSocket(INVALID_SOCKET),
	m_ioCompletePort(NULL),
	m_running(false),m_acceptBuffer(1024){
     }
Server::~Server()
{
     
	//如果我们当前端口是在监听的不是一个引用的时候,就把这个socket关掉
	if (m_listenSocket != INVALID_SOCKET)
		closesocket(m_listenSocket);
	//释放绑定资源
	CloseHandle(m_ioCompletePort);
	CloseHandle(m_completePort);
}




3.server.h

#ifndef YT_WIN_IOCP_SERVER_H
#define YT_WIN_IOCP_SERVER_H
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN

#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include "ServerSock.h"

//using std::vector;

class Server {
     
public:
	//构造函数传入端口号
	Server(u_short port);
	~Server();
	bool startAccept();
	void waitingForAccept();
	//接受客户端发过来的信息用的
	void waitingForIo();
	//检查我们当前的Server是否还OK的
	bool isRunning()const {
      return m_running; }
	void stop() {
      m_running = false; }
	//设置当某事件发生的时候要做什么事情,增加一个回调,newConn是新的回调
	//当有新连接,就产生这个回调newConn
	typedef	std::function<void(ServerSocket::Pointer)> HandleNewConnect;
	HandleNewConnect newConn;
	ServerSocket::HandleRecvFunction socketRecv;
	ServerSocket::HandleClose socketClose;
	ServerSocket::HandleError socketErrro;
private:
	//m_port是我们要监听的端口号
	u_short m_port;
	SOCKET m_listenSocket;
	HANDLE m_completePort;
	LPFN_ACCEPTEX lpfnAcceptEx;
	//当前我们客户端接收的socket
	SOCKET m_currentAccetSocket;
	WSAOVERLAPPED m_acceptUnit;
	HANDLE m_ioCompletePort;
	bool m_running;
	std::vector<char> m_acceptBuffer;
	bool tryNewConn();
};

#endif




你可能感兴趣的:(多线程编程,socket,c++)