📄 px_ss_module_cl.c
字号:
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 + -