📄 dcc_download_generic.cpp
字号:
/* $Id: dcc_download_generic.cpp,v 1.5 2003/09/24 17:53:20 mbn Exp $
**
** ClanLib Game SDK
** Copyright (C) 2003 The ClanLib Team
** For a total list of contributers see the file CREDITS.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with this library; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dcc_download_generic.h"
#include "API/Core/IOData/outputsource_provider.h"
#include "API/Core/IOData/outputsource_file.h"
#include "API/Core/System/system.h"
#include "API/Core/System/event_listener.h"
#include "API/Core/System/error.h"
#include "API/Core/System/log.h"
#ifdef WIN32
#include "winsock.h"
#else
#include <netinet/in.h>
#endif
/////////////////////////////////////////////////////////////////////////////
// CL_DCCDownload_Generic Construction:
CL_DCCDownload_Generic::CL_DCCDownload_Generic(
const std::string &server,
const std::string &port,
const std::string &filename,
int total_size,
CL_OutputSourceProvider *provider,
bool delete_provider)
:
server(server), port(port), filename(filename), total_size(total_size),
provider(provider), delete_provider(delete_provider), status(CL_DCCDownload::connecting),
send_signal(no_signal)
{
thread = CL_Thread(this);
thread.start();
}
CL_DCCDownload_Generic::~CL_DCCDownload_Generic()
{
shutdown_trigger.set_flag();
thread.wait();
if (delete_provider) delete provider;
}
/////////////////////////////////////////////////////////////////////////////
// CL_DCCDownload_Generic Attributes:
/////////////////////////////////////////////////////////////////////////////
// CL_DCCDownload_Generic Operations:
void CL_DCCDownload_Generic::add_ref()
{
ref_count++;
}
void CL_DCCDownload_Generic::release_ref()
{
ref_count--;
if (ref_count == 0) delete this;
}
/////////////////////////////////////////////////////////////////////////////
// CL_DCCDownload_Generic Implementation:
void CL_DCCDownload_Generic::run()
{
while (shutdown_trigger.get_flag() == false)
{
CL_MutexSection mutex_lock(&mutex);
if (status != CL_DCCDownload::connecting)
{
CL_System::sleep(100);
continue;
}
try
{
status = CL_DCCDownload::connecting;
mutex_lock.leave();
CL_Socket sock(CL_Socket::tcp);
sock.connect(CL_IPAddress(server, port));
sock.set_nodelay();
mutex_lock.enter();
status = CL_DCCDownload::downloading;
mutex_lock.leave();
int total_read = 0;
CL_OutputSource_File outputfile(filename);
char buffer[64*1024];
while (true)
{
CL_EventListener listener;
listener.add_trigger(sock.get_read_trigger());
listener.add_trigger(&shutdown_trigger);
listener.add_trigger(&reconnect_trigger);
listener.wait();
if (shutdown_trigger.get_flag()) break;
if (reconnect_trigger.get_flag())
{
reconnect_trigger.reset();
mutex_lock.enter();
status = CL_DCCDownload::connecting;
mutex_lock.leave();
sock = CL_Socket(CL_Socket::tcp);
sock.connect(CL_IPAddress(server, port));
continue;
}
int data_read = sock.input.read(buffer, 64*1024);
if (data_read == 0) break;
total_read += data_read;
outputfile.write(buffer, data_read);
unsigned int total_read_network_order = htonl(total_read);
sock.output.write(&total_read_network_order, 4);
}
mutex_lock.enter();
status = CL_DCCDownload::finished;
send_signal = complete_signal;
mutex_lock.leave();
break;
}
catch (CL_Error err)
{
mutex_lock.enter();
status = CL_DCCDownload::connection_lost;
send_signal = lost_signal;
error = err.message;
mutex_lock.leave();
}
}
}
void CL_DCCDownload_Generic::keep_alive()
{
CL_MutexSection mutex_lock(&mutex);
if (send_signal == complete_signal)
{
send_signal = no_signal;
mutex_lock.leave();
sig_download_complete();
}
else if (send_signal == lost_signal)
{
std::string err = error;
send_signal = no_signal;
mutex_lock.leave();
sig_connection_lost(err);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -