SocketCode_t NetworkMessage::write(SOCKET socket, int32_t timeout/* = NETWORK_RETRY_TIME*/) { if(!m_size) return SOCKET_CODE_OK; m_buffer[2] = (uint8_t)(m_size); m_buffer[3] = (uint8_t)(m_size >> 8); int32_t sent = 0, waiting = 0; do { int32_t ret = send(socket, (char*)m_buffer + sent + NETWORK_HEADER_SIZE, std::min(m_size - sent + NETWORK_HEADER_SIZE, 1000), 0); if(ret <= 0) { if(errno == EWOULDBLOCK) { ret = 0; OTSYS_SLEEP(100); waiting += 100; if(waiting > timeout) return SOCKET_CODE_TIMEOUT; } else return SOCKET_CODE_ERROR; } sent += ret; } while(sent < m_size + NETWORK_HEADER_SIZE); return SOCKET_CODE_OK; }
void Protocol::sleepTillMove() { long long delay = getSleepTicks(); if(delay > 0 ){ #if __DEBUG__ std::cout << "Delaying "<< player->getName() << " --- " << delay << std::endl; #endif OTSYS_SLEEP((uint32_t)delay); } player->lastmove = OTSYS_TIME(); }
int main(int argc, char* argv[]) { #if defined WIN32 || defined __WINDOWS__ WSADATA wsd; if(WSAStartup(MAKEWORD(2,2), &wsd) != 0){ return 1; } LARGE_INTEGER counter; QueryPerformanceCounter(&counter); srand(counter.LowPart); #else srand(time(NULL)); #endif disconnect_function = getCommand("disconnect", true); ping_function = getCommand("ping", true); char command[1024]; long lineCounter = 0; long exit_code = 0; std::stringstream is; if(argc > 1){ for(int i = 1; i < argc; ++i){ is << argv[i] << std::endl; } } else{ is << std::cin.rdbuf(); } while(!is.eof()){ lineCounter++; is.getline(command, 1024); if(strcmp(command, "") != 0){ //comments line if(command[0] == '#'){ continue; } //lower case until first space for(int i = 0; i < strlen(command) && command[i] != ' '; ++i){ command[i] = tolower(command[i]); if(command[i] == '\r'){ command[i] = 0; break; } } if(strlen(command) == 0) continue; CommandLine* commandLine; if(commandLine = parseLine(command)){ commands_queue.push_back(commandLine); } else{ std::cout << "Syntax error in line " << lineCounter << " " << command << std::endl; //clear commands COMMANDS_QUEUE::iterator it; for(it = commands_queue.begin(); it != commands_queue.end(); ++it){ delete[] (*it)->params; delete *it; } commands_queue.clear(); return 1; } } } //execute commands now NetworkMessage msg; COMMANDS_QUEUE::iterator it = commands_queue.begin(); long last_ping = 0; while(it != commands_queue.end()){ OTSYS_SLEEP(250); last_ping = last_ping + 250; if(next_command_delay > 250){ next_command_delay = next_command_delay - 250; } else{ next_command_delay = 0; long long time = OTSYS_TIME(); //execute the command int retCode = (*it)->function((*it)->params); if(retCode == 1){ //everything was ok ++it; } else if(retCode == 2){ //timeout } else{ //error in the command exit_code = 1; break; } last_ping += (OTSYS_TIME() - time); } if(!g_shutdown && last_ping > 10000){ //send ping here ping_function(NULL); last_ping = 0; } } //if connected end the connection if(g_connected){ disconnect_function(NULL); } //free it for(it = commands_queue.begin(); it != commands_queue.end(); ++it){ delete[] (*it)->params; delete *it; } commands_queue.clear(); #if defined WIN32 || defined __WINDOWS__ WSACleanup(); #endif return exit_code; }
SocketCode_t NetworkMessage::read(SOCKET socket, bool ignoreLength, int32_t timeout/* = NETWORK_RETRY_TIME*/) { int32_t waiting = 0, data = NETWORK_DEFAULT_SIZE; if(!ignoreLength) { do { // just read the size to avoid reading 2 messages at once int32_t ret = recv(socket, (char*)m_buffer, NETWORK_HEADER_SIZE, 0); if(ret <= 0) { if(errno == EWOULDBLOCK) { ret = 0; OTSYS_SLEEP(10); waiting += 10; if(waiting > timeout) { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_TIMEOUT; } } else { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_ERROR; } } m_size += ret; } while(m_size < NETWORK_HEADER_SIZE); // for now we expect 2 bytes at once, it should not be splitted data = (int32_t)(m_buffer[0] | m_buffer[1] << 8); if(m_size != NETWORK_HEADER_SIZE || data > NETWORK_MAX_SIZE - NETWORK_HEADER_SIZE) { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_ERROR; } } int32_t recvd = 0; do { // read the real data int32_t ret = recv(socket, (char*)m_buffer + recvd + NETWORK_HEADER_SIZE, data - recvd, 0); if(ret <= 0) { if(errno == EWOULDBLOCK) { ret = 0; OTSYS_SLEEP(100); waiting += 100; if(waiting > timeout) { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_TIMEOUT; } } else if(data == NETWORK_DEFAULT_SIZE) break; else { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_ERROR; } } recvd += ret; } while(recvd < data); m_size += recvd; // we got something unexpected/incomplete if(m_size <= NETWORK_HEADER_SIZE || (!ignoreLength && m_size - NETWORK_HEADER_SIZE != data)) { reset(NETWORK_HEADER_SIZE); return SOCKET_CODE_ERROR; } m_position = NETWORK_HEADER_SIZE; return SOCKET_CODE_OK; }