// sender uses the function int send_file(int sock, struct sockaddr_in *recv_adr, char *filename, akh_disconn_response *disconn_response) { uint32_t seg_size = disconn_response->segment_size; uint32_t req_num = disconn_response->segment_num; uint32_t *seg_list = disconn_response->segment_list; uint32_t seg_num; akh_pdu_header header; char buf[MAX_BUFFER_SIZE]; packet pac; size_t buf_len, pac_len; int i; for(i = 0; i < req_num; i++) { seg_num = seg_list[i]; header = createHeader(SS, seg_num); buf_len = read_segment(buf, seg_size, seg_num, filename); pac_len = createPacket(&pac, &header, buf, buf_len); sendto(sock, pac, pac_len, 0, (struct sockaddr *)recv_adr, sizeof(*recv_adr)); deletePacket(pac); puts("< send file segment >"); displayHeader(header); } return 0; }
ClientCommunicator::~ClientCommunicator() { deletePacket(Pin); deletePacket(Pout); Pin = nullptr; Pout = nullptr; for(auto it=O.begin(); it != O.end(); it++){ deletePacket((*it)); (*it) = nullptr; } O.clear(); for(auto it=R.begin(); it != R.end(); it++){ deletePacket((*it)); (*it) = nullptr; } R.clear(); }
bool ClientCommunicator::hasNextPacket(std::string &head, unsigned int &len, unsigned int &rpt, char **data) { if(R.empty()) return false; Packet *pkt = R.front(); R.pop_front(); head = ""; head.append(1, pkt->hdr.pckType[0]); head.append(1, pkt->hdr.pckType[1]); head.append(1, pkt->hdr.pckType[2]); head.append(1, pkt->hdr.pckType[3]); len = pkt->hdr.len; rpt = pkt->hdr.replyAddr; *data = nullptr; if(len > 0){ *data = new char[len]; memcpy(*data, pkt->data, len); } deletePacket(pkt); return true; }
void PacketManager::worker() { try { std::chrono::milliseconds sleepingTime(1000); uint32_t counter = 0; int32_t lastPacket; lastPacket = 0; while(!_stopWorkerThread) { try { std::this_thread::sleep_for(sleepingTime); if(_stopWorkerThread) return; if(counter > 100) { counter = 0; _packetMutex.lock(); if(_packets.size() > 0) { int32_t packetsPerSecond = (_packets.size() * 1000) / sleepingTime.count(); if(packetsPerSecond <= 0) packetsPerSecond = 1; int32_t timePerPacket = (GD::bl->settings.workerThreadWindow() * 10) / packetsPerSecond; if(timePerPacket < 10) timePerPacket = 10; sleepingTime = std::chrono::milliseconds(timePerPacket); } _packetMutex.unlock(); } _packetMutex.lock(); if(!_packets.empty()) { std::unordered_map<int32_t, std::shared_ptr<PhilipsHuePacketInfo>>::iterator nextPacket = _packets.find(lastPacket); if(nextPacket != _packets.end()) { nextPacket++; if(nextPacket == _packets.end()) nextPacket = _packets.begin(); } else nextPacket = _packets.begin(); lastPacket = nextPacket->first; } std::shared_ptr<PhilipsHuePacketInfo> packet; if(_packets.find(lastPacket) != _packets.end()) packet = _packets.at(lastPacket); _packetMutex.unlock(); if(packet) deletePacket(lastPacket, packet->id); counter++; } catch(const std::exception& ex) { _packetMutex.unlock(); GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { _packetMutex.unlock(); GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { _packetMutex.unlock(); GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } } } catch(const std::exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(BaseLib::Exception& ex) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what()); } catch(...) { GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__); } }
bool ClientCommunicator::update() { if(!nosocket){ // need to read if data has been sent if(bytesIn < sizeof(PacketHeader)){ //we are reading the header still int count = recv(sock, (char*)(Pin)+bytesIn, sizeof(PacketHeader)-bytesIn, 0); if(count == 0){ std::cout << "Client Disconnected [" << ID << "]\n"; close(); return false; } if(count < 0 && !wouldBeBlocked){ std::cout << "Client Disconnected [" << ID << "]\n"; close(); return false; } if(count > 0){ bytesIn += count; } if(bytesIn == sizeof(PacketHeader)){ // header fully read // fix byte ordering Pin->hdr.magic = ntohl(Pin->hdr.magic); Pin->hdr.len = ntohl(Pin->hdr.len); Pin->hdr.replyAddr = ntohl(Pin->hdr.replyAddr); // verify integrity if(Pin->hdr.magic != MAGIC){ std::cout << "Kicking Client " << ID << " for packet w/o MAGIC ID\n"; close(); return false; } if(Pin->hdr.len > MAXSZ){ std::cout << "Kicking Client " << ID << " for sending packet over 32MB\n"; close(); return false; } if(Pin->hdr.len > 0){ assert(Pin->data == nullptr); Pin->data = new char[Pin->hdr.len]; } } } if(bytesIn >= sizeof(PacketHeader) && Pin->hdr.len > 0){ // read data section char* ptr = ((char*)Pin->data)+(bytesIn-sizeof(PacketHeader)); int count = recv(sock, ptr, (Pin->hdr.len+sizeof(PacketHeader))-bytesIn, 0); if(count == 0){ std::cout << "Client Disconnected [" << ID << "]\n"; close(); return false; } if(count < 0 && !wouldBeBlocked){ std::cout << "Client Disconnected [" << ID << "]\n"; close(); return false; } if(count > 0){ bytesIn += count; } if(bytesIn == Pin->hdr.len + sizeof(PacketHeader)){ // entire packet read -> reset reader R.push_back(Pin); Pin = new Packet(nullptr); bytesIn = 0; } }else if(bytesIn == sizeof(PacketHeader) && Pin->hdr.len == 0){ R.push_back(Pin); Pin = new Packet(nullptr); bytesIn = 0; } // Now let's send some data out if(Pout == nullptr && O.size() > 0){ Pout = O.front(); O.pop_front(); bytesOut = 0; } if(Pout != nullptr){ if(bytesOut < sizeof(PacketHeader)){ // send out header int count = send(sock, (char*)(Pout)+bytesOut, sizeof(PacketHeader)-bytesOut, 0); if(count < 0 && !wouldBeBlocked){ std::cout << "Client Write Failed [" << ID << "] Kicking...\n"; std::cout << " CASE A" << errno << "\n"; close(); return false; } if(count > 0){ bytesOut += count; } } if(bytesOut == sizeof(PacketHeader)){ // change length back to host to compare later Pout->hdr.len = ntohl(Pout->hdr.len); } if(bytesOut >= sizeof(PacketHeader) && Pout->hdr.len > 0){ // write data section if(Pout->data != nullptr){ ssize_t count = send(sock, Pout->data+(bytesOut-sizeof(PacketHeader)), Pout->hdr.len-(bytesOut-sizeof(PacketHeader)), 0); if(count < 0 && !wouldBeBlocked && !bufferFull){ std::cout << "Client Write Failed [" << ID << "] Kicking...\n"; std::cout << " CASE B[DataSend]" << errno << "\n"; close(); return false; } if(count > 0){ bytesOut += count; } }else{ char buf[1024]; long unsigned int bytesLeft = std::min((long unsigned int)1024, (long unsigned int)Pout->hdr.len-(bytesOut-sizeof(PacketHeader))); Pout->fl->read((char*)&buf, bytesLeft); if(!Pout->fl){ std::cout << "Client Write Failed [Reading Packet File]...\n"; deletePacket(Pout); Pout = nullptr; return false; } ssize_t count = send(sock, (char*)&buf, bytesLeft, 0); if(count < 0 && !wouldBeBlocked && !bufferFull){ std::cout << "Client Write Failed [" << ID << "] Kicking...\n"; std::cout << " CASE B[FileSend]" << errno << "\n"; close(); return false; } Pout->fl->seekg(count-bytesLeft, std::ios_base::cur); if(count > 0){ bytesOut += count; } } } if(bytesOut >= sizeof(PacketHeader) && bytesOut == sizeof(PacketHeader)+Pout->hdr.len){ // done sending deletePacket(Pout); Pout = nullptr; } } }else{ // first check for any nesseary read operations [sin.lck exists] std::string inlock = DirectoryManager::getSingleton()->getRootDirectory()+"sin.lck"; FILE *fp = fopen(inlock.c_str(),"r"); if(fp != NULL){ // read the packets std::string infl = DirectoryManager::getSingleton()->getRootDirectory()+"sin.sck"; FILE *fp2 = fopen(infl.c_str(),"rb"); if(fp2 != NULL){ Packet *pkt = new Packet(nullptr); // read the header [Only one packet allowed at a time] unsigned int count = fread(&pkt->hdr, 1, sizeof(PacketHeader), fp2); if(count == sizeof(PacketHeader)){ // okay to continue reading // fix byte ordering pkt->hdr.magic = ntohl(pkt->hdr.magic); pkt->hdr.len = ntohl(pkt->hdr.len); pkt->hdr.replyAddr = ntohl(pkt->hdr.replyAddr); // verify integrity if(pkt->hdr.magic == MAGIC && pkt->hdr.len <= MAXSZ){ if(Pin->hdr.len > 0){ assert(pkt->data == nullptr); pkt->data = new char[pkt->hdr.len]; count = fread(pkt->data, 1, pkt->hdr.len, fp2); if(count == pkt->hdr.len){ R.push_back(pkt); }else{ deletePacket(pkt); pkt = nullptr; } }else{ R.push_back(pkt); } }else{ deletePacket(pkt); pkt = nullptr; } }else{ pkt->data = nullptr; // in case this got corrupt nothing was allocated deletePacket(pkt); pkt = nullptr; } // clear the file fclose(fp2); fp2 = fopen(infl.c_str(),"wb"); fclose(fp2); } // finally destroy the lock fclose(fp); remove(inlock.c_str()); } // now send a packet if one exists if(O.size() > 0){ Packet *pkt = O.front(); O.pop_front(); // make sure lock is gone std::string outlock = DirectoryManager::getSingleton()->getRootDirectory()+"sout.lck"; FILE *fp = fopen(outlock.c_str(), "r"); if(fp != NULL){ fclose(fp); }else{ std::string outfl = DirectoryManager::getSingleton()->getRootDirectory()+"sout.sck"; fp = fopen(outfl.c_str(), "wb"); // write header fwrite(&pkt->hdr, sizeof(PacketHeader), 1, fp); // now write data (if it exists) unsigned int len = ntohl(pkt->hdr.len); if(len > 0){ if(pkt->data != nullptr){ fwrite(pkt->data, len, 1, fp); }else{ char buf[1024]; long int lenSent = 0; while(lenSent < len){ long int bytesLeft = std::min((long int)1024, (long int)len-lenSent); pkt->fl->read((char*)&buf, bytesLeft); if(!Pout->fl){ std::cout << "Client Write Failed [Reading Packet File]...\n"; break; } fwrite(&buf, bytesLeft, 1, fp); lenSent += bytesLeft; } } } fclose(fp); // write lock fp = fopen(outlock.c_str(), "wb"); fclose(fp); } } } return true; }