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

📄 px_ss_module_cl.c

📁 MMORPG游戏服务器端架构及函数
💻 C
📖 第 1 页 / 共 3 页
字号:
	PX_SS_CL_KEY  * pck;
	PX_SS_CL_INFO * pci;
	for(i = 0;i < g_stat->num_cl_key;i ++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}
		if (pck->state != STATE_KEY_NORMAL_USE) {
			continue;
		}
		shutdown(pck->prdi->per_data->pcli->s_client,SD_BOTH);
		closesocket(pck->prdi->per_data->pcli->s_client);
		set_specify_cl_state(pck->prdi->per_data->pcli,STATE_PX_SS_CL_DISCONNECTED);
	}
	return;
}

void close_module_cl(){
	PX_SS_CL_PER_DATA * per_data;
	PX_SS_CL_IO_DATA  * io_data;
	DWORD bytes_trans = 1;
	SOCKET sck_t = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
	if(connect(sck_t,(SOCKADDR *)&addr_module_cl,sizeof(addr_module_cl)) ==0){
		closesocket(sck_t);
	}
	SetEvent(h_event_module_cl);
	if (g_stat->num_thread_cl > 0) {
		per_data = (LPPX_SS_CL_PER_DATA)ms_malloc(sizeof(PX_SS_CL_PER_DATA));
		io_data = (LPPX_SS_CL_IO_DATA)ms_malloc(sizeof(PX_SS_CL_IO_DATA));
		memset(io_data,0,sizeof(OVERLAPPED));
		io_data->io_type = IOCP_IO_TYPE_POST_QUIT_THREAD;
		if (!PostQueuedCompletionStatus(h_iocp_module_cl,&bytes_trans,(DWORD)per_data,&(io_data->overlapped))) {
			ms_free(io_data);
			io_data = NULL;
			ms_free(per_data);
			per_data = NULL;
		}
	}
	return;
}

void free_module_cl_resource(){
	int i;
	PX_SS_CL_KEY * pck;
	PX_SS_CL_INFO * pci;
	for(i = 0;i < g_stat->num_cl_key;i++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}
		pci = pck->prdi->per_data->pcli;
		//free pci member cts
		DeleteCriticalSection(pci->cts_state);
		ms_free(pci->cts_state);
		pci->cts_state = NULL;
		DeleteCriticalSection(pci->cts_recv);
		ms_free(pci->cts_recv);
		pci->cts_recv = NULL;
		DeleteCriticalSection(pci->cts_send);
		ms_free(pci->cts_send);
		pci->cts_send = NULL;
		//free pci member pointer
		if (pci->recv_buf != NULL) {
			ms_free(pci->recv_buf);
			pci->recv_buf = NULL;
		}
		if (pci->precv_append != NULL) {
			ms_free(pci->precv_append);
			pci->precv_append = NULL;
		}
		if (pci->send_buf != NULL) {
			ms_free(pci->send_buf);
			pci->send_buf = NULL;
		}
		if (pci->psend_append != NULL) {
			ms_free(pci->psend_append);
			pci->psend_append = NULL;
		}
		//free pci
		ms_free(pci);
		pci = NULL;
		//free per_data
		ms_free(pck->prdi->per_data);
		pck->prdi->per_data = NULL;
		//free io_recv
		if (pck->prdi->io_recv->buf != NULL) {
			ms_free(pck->prdi->io_recv->buf);
			pck->prdi->io_recv->buf = NULL;
		}
		ms_free(pck->prdi->io_recv);
		pck->prdi->io_recv = NULL;
		//free io_send
		if (pck->prdi->io_send->buf != NULL) {
			ms_free(pck->prdi->io_send->buf);
			pck->prdi->io_send->buf = NULL;
		}
		ms_free(pck->prdi->io_send);
		pck->prdi->io_send = NULL;
		//free redirect
		ms_free(pck->prdi);
		pck->prdi = NULL;
	}
	//free cl key
	ms_free(module_cl_key_head);
	module_cl_key_head = NULL;
	g_stat->num_cl_key = 0;
	return;
}

void handle_module_cl_recv_buf(){
	int i;
	PX_SS_CL_KEY * pck;
	for(i = 0;i < g_stat->num_cl_key;i++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}
		if (pck->state != STATE_KEY_NORMAL_USE) {
			continue;
		}
		handle_specify_cl_recv_buf(pck->prdi->per_data->pcli);
	}
	return;
}

void handle_specify_cl_recv_buf(PX_SS_CL_INFO * pci){
	WORD mc;
	WORD size;
	int surplus_size;
	char * packet;
	char * poffset;
	if (g_time_service->frame_theory - pci->frame_prev <= 3) {
		return;
	}
	if (valid_specify_cl_state(pci,STATE_PX_SS_CL_CONNECTED)) {
		if (g_time_service->frame_theory - pci->frame_prev >= 60*3) {
			shutdown(pci->s_client,SD_BOTH);
			closesocket(pci->s_client);
			set_specify_cl_state(pci,STATE_PX_SS_CL_CONNECTED);
		}
	}
	tidy_specify_cl_recv_buf(pci);
	while (TRUE) {
		EnterCriticalSection(pci->cts_recv);
		surplus_size = pci->precv_end - pci->precv_start;
		if (surplus_size < 2) {
			LeaveCriticalSection(pci->cts_recv);
			break;
		}
		poffset = pci->precv_start;
		memcpy(&mc,poffset,sizeof(WORD));
		poffset += sizeof(WORD);
		if ((mc <= MCCL_SS_START)||(mc > MCCL_SS_FINAL)) {
			LeaveCriticalSection(pci->cts_recv);
			close_specify_client(pci);
			break;
		}
		size = pxmc[mc];
		if (size < 0) {
			surplus_size = pci->precv_end - poffset;
			if (surplus_size < 2) {
				LeaveCriticalSection(pci->cts_recv);
				break;
			}else{
				memcpy(&size,poffset,sizeof(size));
				poffset += sizeof(WORD);
			}
		}
		surplus_size = pci->precv_end - poffset;
		if (surplus_size < size) {
			LeaveCriticalSection(pci->cts_recv);
			break;
		}else{
			poffset += size;
			LeaveCriticalSection(pci->cts_recv);
			handle_module_cl_packet(pci, mc, size,poffset);
			
		}
	}
	return;
}

void handle_module_cl_packet(PX_SS_CL_INFO * pci,WORD mc,WORD size,char * packet){
	switch(mc) {
	case MCCL_SS_REQUEST_CONNECT:
		module_cl_packet_request_connect( pci, size, packet);
		break;
	case MCCL_SS_SEND_VERSION:
		module_cl_packet_send_version( pci, size, packet);
		break;
	case MCCL_SS_SEND_MD5_CODE:
		module_cl_packet_send_md5_code( pci, size, packet);
		break;
	case MCCL_SS_SEND_SPECIFY_CODE:
		module_cl_packet_send_specify_code( pci, size, packet);
		break;
	case MCCL_SS_REQUEST_GET_AREA_SERVER_LIST:
		module_cl_packet_request_get_area_server_list( pci, size, packet);
		break;
	case MCCL_SS_REQUEST_GET_SERVER_LIST:
		module_cl_packet_request_get_server_list( pci, size, packet);
		break;
	case MCCL_SS_REQUEST_GET_LINE_SERVER_LIST:
		module_cl_packet_request_get_line_server_list( pci, size, packet);
		break;
	case MCCL_SS_REQUEST_GET_SPECIFY_LINE_SERVER_ADDRESS:
		module_cl_packet_request_specify_line_server_address( pci, size, packet);
		break;
	case MCCL_SS_SEND_HEARTBREAK:
		module_cl_packet_send_heartbreak( pci, size, packet);
		break;
	case MCCL_SS_REQUEST_DISCONNECT:
		module_cl_packet_request_disconnect( pci, size, packet);
		break;
	case MCCL_SS_SEND_FRAME_COUNTER:
		module_cl_packet_send_frame_counter( pci, size, packet);
		break;
	default:
		break;
	}
	return ;
}

void handle_module_cl_heartbreak(){
	int i;
	int size = 6;
	char cache[6];
	WORD mc = MC_SS_CL_SEND_HEARTBREAK;
	PX_SS_CL_KEY * pck;
	PX_SS_CL_INFO * pci;
	for(i = 0;i < g_stat->num_cl_key;i++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}
		if (pck->state != STATE_KEY_NORMAL_USE) {
			continue;
		}
		if (valid_specify_cl_state(pck->prdi->per_data->pcli,STATE_PX_SS_CL_DISCONNECTED)) {
			continue;
		}
		pci = pck->prdi->per_data->pcli;
		if (g_time_service->frame_theory - pci->frame_heartbreak > 60*4) {
			close_specify_client(pci);
		}else if (g_time_service->frame_theory - pci->frame_heartbreak > 60*2) {
			memcpy(cache,&mc,sizeof(WORD));
			memcpy(cache+2,&pci->heartbreak,sizeof(int));
			add_buf_to_specify_cl_send_buf(pci,size,cache);
		}
	}
	return;
}

void handle_module_cl_reuse(){
	int i;
	PX_SS_CL_KEY * pck;
	PX_SS_CL_INFO * pci;
	for(i = 0;i < g_stat->num_cl_key;i++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}else if (pck->state == STATE_KEY_REUSE_PROCESS) {
			if (g_time_service->frame_theory - pck->prdi->per_data->pcli->frame_prev > 60*5) {
				pck->state = STATE_KEY_FREE_USE;
			}
		}else if (pck->state == STATE_KEY_INACTIVE) {
			set_specify_cl_state(pck->prdi->per_data->pcli,STATE_PX_SS_CL_REUSE_PROCESS);
			pck->state = STATE_KEY_FREE_USE;
		}
	}
	return;
}

void send_all_cl_ss_need_close(){
	int i;
	PX_SS_CL_KEY * pck;
	PX_SS_CL_INFO * pci;
	WORD mc = MC_SS_CL_SEND_NEED_CLOSE;
	int n = 2;
	char cache[2];
	for(i = 0;i < g_stat->num_cl_key;i++){
		pck = module_cl_key_head + i;
		if (pck->state == STATE_KEY_NO_INIT) {
			break;
		}else if (pck->state != STATE_KEY_NORMAL_USE) {
			continue;
		}
		memcpy(cache,&mc,sizeof(WORD));
		add_buf_to_specify_cl_send_buf(pck->prdi->per_data->pcli,n,cache);
	}
	return;
}

DWORD WINAPI module_cl_accept_thread(PVOID paparm){
	int iret;
	int len;
	int i;
	unsigned int ip;
	DWORD byte_recv;
	DWORD flags;
	BOOL found = FALSE;
	u_short port;
	SOCKET sck_t;
	SOCKADDR_IN addr_t;
	PX_SS_CL_KEY * pck;
	WaitForSingleObject(h_event_module_cl,INFINITE);
	if (!valid_ss_state(STATE_MAIN_RUN)) {
		return 0;
	}
	for(i = 0;i < g_config->num_cl_iocp_thread;i++){
		_beginthread(module_cl_iocp_thread,0,h_iocp_module_cl);
		g_stat->num_thread_cl++;
	}
	iret = listen(sck_module_cl,10);
	if (iret == SOCKET_ERROR) {
		x_debug_error("listen for module cl fail");
		set_module_cl_state(STATE_MODULE_ERROR_FOUND);
		return 0;
	}
	while (TRUE) {
		memset(&addr_t,0,sizeof(addr_t));
		len = sizeof(addr_t);
		sck_t = accept(sck_module_cl,(SOCKADDR *)&addr_t,&len);
		if (sck_t == INVALID_SOCKET) {
			x_debug_error("accept return wrong socket for module cl");
			if (valid_ss_state(STATE_MAIN_RUN)) {
				continue;
			}else{
				return 0;
			}
		}
		ip = get_ip_by_sockaddr(&addr_t);
		port = get_port_by_sockaddr(&addr_t);
		if (ip == g_config->ip_local) {
			if (valid_ss_state(STATE_MAIN_REQUEST_CLOSE)) {
				shutdown(sck_t,SD_BOTH);
				closesocket(sck_t);
				return 0;
			}else if (!g_config->accept_internal_ip) {
				shutdown(sck_t,SD_BOTH);
				closesocket(sck_t);
				return 0;
			}
		}
		found = FALSE;
		for(i = 0;i < g_stat->num_cl_key;i++){
			pck = module_cl_key_head + i;
			if ((pck->state == STATE_KEY_NO_INIT)||(pck->state == STATE_KEY_FREE_USE)) {
				found = TRUE;
				break;
			}
		}
		if (!found) {
			shutdown(sck_t,SD_BOTH);
			closesocket(sck_t);
			continue;
		}
		if (pck->state == STATE_KEY_NO_INIT) {
			init_cl_key_new(pck);
		}else{
			init_cl_key_reuse(pck);
		}

		//set pck other member
		pck->prdi->per_data->pcli->ip = ip;
		pck->prdi->per_data->pcli->port = port;
		pck->prdi->per_data->pcli->s_client = sck_t;

		//bind sck_t with iocp
		if (CreateIoCompletionPort((HANDLE)sck_t,h_iocp_module_cl,(DWORD)pck->prdi->per_data,0) == NULL) {
			shutdown(sck_t,SD_BOTH);
			closesocket(sck_t);
			set_specify_cl_state(pck->prdi->per_data,STATE_PX_SS_CL_DISCONNECTED);
			continue;
		}

		//WSARecv 
		byte_recv = 0;
		flags = 0;
		iret = WSARecv(sck_t,&(pck->prdi->io_recv->wsabuf),1,&byte_recv,&flags,&(pck->prdi\
			->io_recv->overlapped),NULL);
		if ((iret == 0)||((iret == SOCKET_ERROR)&&(WSAGetLastError() == WSA_IO_PENDING))) {
			//succ
		}else{
			shutdown(sck_t,SD_BOTH);
			closesocket(sck_t);
			set_specify_cl_state(pck->prdi->per_data,STATE_PX_SS_CL_DISCONNECTED);
			continue;
		}
	}
	return 0;
}

DWORD WINAPI module_cl_iocp_thread(PVOID paparm){
	HANDLE				iocp = (HANDLE)paparm;
	DWORD				bytes_trans;
	LPOVERLAPPED		overlapped;
	LPPX_SS_CL_PER_DATA	per_data;
	LPPX_SS_CL_IO_DATA	io_data;
	PX_SS_CL_KEY		**	plsk;
	DWORD				send_bytes;
	DWORD				recv_bytes;

⌨️ 快捷键说明

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