void SocketMultiplexer::ControlLoop() { control_socket_ = CreateSocket(config_.control_socket_path); Unlinker u_control_socket(config_.control_socket_path); FDCloser c_control_socket(control_socket_); if (control_socket_ < 0) { ELOG(ERROR, "CreateSocket()", errno); return; } while (true) { int control_fd = AcceptSocket(control_socket_); if (control_fd < 0 && errno == EINVAL) { break; } if (control_fd < 0) { ELOG(ERROR, "AcceptSocket()", errno); break; } std::thread t([this](int control_fd) { FDCloser c_control_fd(control_fd); char buf[1024]; int uid; int ret = PeekSocketCredentials(control_fd, NULL, &uid, NULL); if (ret < 0) { ELOG(ERROR, "PeekSocketCredentials()", errno); return; } while (true) { int recved = recv(control_fd, buf, 1024, 0); if (recved < 0) { ELOG(ERROR, "recv", errno); break; } if (recved == 0) { break; } std::istringstream iss(std::string(buf, recved)); std::string line; while (std::getline(iss, line)) { std::string result = this->DispatchCommand(uid, line); send(control_fd, result.c_str(), result.size(), 0); } } }, control_fd); t.detach(); } }
void SocketMultiplexer::MainLoop() { master_socket_ = CreateSocket(config_.master_socket_path); Unlinker u_master_socket(config_.master_socket_path); FDCloser c_master_socket(master_socket_); if (master_socket_ < 0) { ELOG(ERROR, "CreateSocket()", errno); return; } while (true) { int master_fd = AcceptSocket(master_socket_); if (master_fd < 0 && errno == EINVAL) { break; } if (master_fd < 0) { ELOG(ERROR, "AcceptSocket()", errno); break; } std::thread t([this](int master_fd) { FDCloser c_master_fd(master_fd); int uid; int ret = PeekSocketCredentials(master_fd, NULL, &uid, NULL); if (ret < 0) { ELOG(ERROR, "PeekSocketCredentials()", errno); return; } int slave_fd = this->TryConnectActiveSocket(uid); FDCloser c_slave_fd(slave_fd); if (slave_fd < 0) { ELOG(ERROR, "TryConnectActiveSocket()", errno); return; } SocketCoupler(master_fd, slave_fd); }, master_fd); t.detach(); } }
//----------------------------------------------------------------------------- int main(int argc, char** argv) { if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_EVENTS) != 0) { fprintf(stderr, "ER: SDL_Init: %s\n", SDL_GetError()); exit(-1); } if(SDLNet_Init() == -1) { fprintf(stderr, "ER: SDLNet_Init: %s\n", SDLNet_GetError()); exit(-1); } IPaddress ip; if(SDLNet_ResolveHost(&ip, NULL, 8099) == -1) { fprintf(stderr, "ER: SDLNet_ResolveHost: %s\n", SDLNet_GetError()); exit(-1); } sockets[SERVER_SOCKET] = SDLNet_TCP_Open(&ip); if(sockets[SERVER_SOCKET] == NULL) { fprintf(stderr, "ER: SDLNet_TCP_Open: %s\n", SDLNet_GetError()); exit(-1); } socket_set = SDLNet_AllocSocketSet(MAX_SOCKETS); if(socket_set == NULL) { fprintf(stderr, "ER: SDLNet_AllocSocketSet: %s\n", SDLNet_GetError()); exit(-1); } if(SDLNet_TCP_AddSocket(socket_set, sockets[SERVER_SOCKET]) == -1) { fprintf(stderr, "ER: SDLNet_TCP_AddSocket: %s\n", SDLNet_GetError()); exit(-1); } int running = 1; while(running) { int num_rdy = SDLNet_CheckSockets(socket_set, 1000); if(num_rdy <= 0) { // NOTE: none of the sockets are ready int ind; for(ind=0; ind<MAX_SOCKETS; ++ind) { if(!clients[ind].in_use) continue; /* if(clients[ind].questing && (SDL_GetTicks()-clients[ind].timer_wood)>WOOD_WAIT_TIME ) { clients[ind].questing = 0; clients[ind].amt_wood += 4; char msg[0xFF] = "> quest complete\n\r"; SendData(ind, msg, (strlen(msg)+1)); } */ clients[ind].amt_wood += 4; /* uint16_t length = 0; uint8_t data[MAX_PACKET]; memcpy(data+length, &clients[ind].amt_wood, sizeof(uint8_t)); length += sizeof(uint8_t); SendData(ind, data, length, FLAG_WOOD_UPDATE); */ } } else { int ind; for(ind=0; (ind<MAX_SOCKETS) && num_rdy; ++ind) { if(sockets[ind] == NULL) continue; if(!SDLNet_SocketReady(sockets[ind])) continue; if(ind == SERVER_SOCKET) { int got_socket = AcceptSocket(next_ind); if(!got_socket) { num_rdy--; continue; } // NOTE: get a new index int chk_count; for(chk_count=0; chk_count<MAX_SOCKETS; ++chk_count) { if(sockets[(next_ind+chk_count)%MAX_SOCKETS] == NULL) break; } next_ind = (next_ind+chk_count)%MAX_SOCKETS; printf("DB: new connection (next_ind = %d)\n", next_ind); num_rdy--; } else { uint8_t* data; uint16_t flag; uint16_t length; data = RecvData(ind, &length, &flag); if(data == NULL) { num_rdy--; continue; } switch(flag) { case FLAG_WOOD_UPDATE: { uint16_t offset = 0; uint8_t send_data[MAX_PACKET]; memcpy(send_data+offset, &clients[ind].amt_wood, sizeof(uint8_t)); offset += sizeof(uint8_t); SendData(ind, send_data, offset, FLAG_WOOD_UPDATE); } break; } /* uint8_t* data; int length; data = RecvData(ind, &length); if(data == NULL) { num_rdy--; continue; } int i; for(i=0; i<length; ++i) { if(data[i] == '\n') data[i] = '\0'; if(data[i] == '\r') data[i] = '\0'; } // TEMP: add a NULL terminator data = (uint8_t*) realloc(data, (length+1)); data[length] = '\0'; int was_processed = 0; if(!strcmp(data, "exit")) { was_processed = 1; running = 0; } else if(!strcmp(data, "quit")) { was_processed = 1; CloseSocket(ind); } else if(!strcmp(data, "get data")) { was_processed = 1; char msg[0xFF] = {}; sprintf(msg, "> wood: %d\n\r", clients[ind].amt_wood); //SendData(ind, msg, (strlen(msg)+1)); } else if(!strcmp(data, "quest")) { was_processed = 1; if(!clients[ind].questing) { clients[ind].questing = 1; clients[ind].timer_wood = SDL_GetTicks(); char msg[0xFF] = "> started quest\n\r"; //SendData(ind, msg, (strlen(msg)+1)); } else { char msg[0xFF] = "> currently running quest\n\r"; //SendData(ind, msg, (strlen(msg)+1)); } } if(was_processed) printf("PR: %s\n", data); free(data); */ num_rdy--; } } } } int i; for(i=0; i<MAX_SOCKETS; ++i) { if(sockets[i] == NULL) continue; CloseSocket(i); } SDLNet_FreeSocketSet(socket_set); SDLNet_Quit(); SDL_Quit(); return 0; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; LPMINMAXINFO minInfo; static SOCKET serverSocket; static SOCKET clientSocket; switch (message) { case WM_CREATE: serverSocket = CreateSocket(hWnd); connectionStatus = statusNotConnected; EnableMenuItem(GetMenu(hWnd), IDM_DISCONNECT, MF_BYCOMMAND | MF_GRAYED); ListAddresses(); break; case WM_NETWORK: switch (WSAGETSELECTEVENT(lParam)) { case FD_ACCEPT: clientSocket = AcceptSocket(hWnd, serverSocket); break; case FD_CLOSE: if (connectionStatus == statusConnected) CloseSocket(hWnd, clientSocket); break; } break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: Shell_NotifyIcon(NIM_DELETE, &trayIcon[trayIconNotConnected]); DestroyWindow(hWnd); break; case IDM_TRAY: HideInTray(hWnd, TRUE); break; case IDM_DISCONNECT: if (connectionStatus == statusConnected) CloseSocket(hWnd, clientSocket); break; case IDM_OPEN: HideInTray(hWnd, FALSE); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_GETMINMAXINFO: minInfo = (LPMINMAXINFO)lParam; minInfo->ptMinTrackSize.x = kWidthMin; minInfo->ptMinTrackSize.y = kHeightMin; break; case WM_PAINT: DisplayWindow(hWnd); break; case WM_SYSCOMMAND: if (wParam == SC_MINIMIZE) HideInTray(hWnd, TRUE); else return DefWindowProc(hWnd, message, wParam, lParam); break; case WM_CLOSE: HideInTray(hWnd, TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; case WM_TRAYMENU: if (wParam == kTrayId) { switch (lParam) { case WM_RBUTTONDOWN: DisplayTrayMenu(hWnd); break; case WM_LBUTTONDBLCLK: HideInTray(hWnd, !bInTray); break; default: break; } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
int CXSPAsyncSocket::SocketIOEpollWait(int timeout) { while(true) { pthread_t thrid = pthread_self(); EpollWaitObject *pEwobj=NULL; if(this->m_ThreadId2Ewobj.Find(thrid, pEwobj) != 0) { pthread_exit((void *)"the map without the thread data"); break; } int &epollId = pEwobj->epollId; vector<EPOLLEVENT> &vEvents = pEwobj->vEvents; volatile int &maxEvent = pEwobj->maxEvent; SIGSETT &sigset = pEwobj->sigset; int ret = epoll_pwait(epollId, &vEvents[0], maxEvent, timeout, &sigset); if(0 == ret) continue;//timeout else if(0 > ret) { err_ret(GetLastError(ERROR_EPOLL_WAIT)); if(EINTR == errno || EAGAIN == errno) continue; pthread_exit((void *)"epoll pwait error"); return -1; } int &fds = ret;//监听套接子的个数 for(int i=0; i<fds && i<maxEvent; ++i) { struct sockaddr addr; EPOLLEVENT &event = vEvents[i]; if(m_socket.sock_fd == event.data.fd) { int clifd = 0; while( 0 < (clifd = AcceptSocket(&addr)) ) { SetAsyncSocket(clifd); SocketEpollAdd(clifd, EPOLLET | EPOLLIN | EPOLLET); #ifndef Debug printf("Add epoll event %d", clifd); #endif } if(-1 == clifd && errno != EAGAIN && ECONNABORTED !=errno && EPROTO!=errno && EINTR != errno) { err_ret(GetLastError(ERROR_ACCEPT_SOCK)); } continue; } else if(EPOLLIN & event.events)//read data { int &fd = event.data.fd; string szRecvData; szRecvData.resize(4); int reLen = 0, offset=0; while((reLen=read(fd, &szRecvData[offset], 4)) > 0) { offset += reLen; szRecvData.resize(offset+1024); } if((reLen < 0 && errno==ECONNRESET) || (0 == reLen) ) { close(fd); SocketEpollDel(fd, event.events); continue; } else if(reLen < 0) continue; szRecvData.resize(offset); this->m_deque.PushBack(szRecvData); #ifndef Debug printf("recv epoll data from %d", fd); #endif } else if(EPOLLOUT & event.events )//write data { int &fd = event.data.fd; string szSendData = (char *)event.data.ptr; int datalen = szSendData.size(), sendlen=0; while(0 < datalen) { sendlen=write(fd, szSendData.c_str(), datalen); if(sendlen < 0) { if(-1 == sendlen && errno != EAGAIN) { err_ret(GetLastError(ERROR_SEND_SOCK)); } break; } datalen -= sendlen; } } } } return 0; }