Exemplo n.º 1
0
// 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;
}
Exemplo n.º 4
0
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;
}