📄 main.cpp
字号:
return true;
}
bool CSender::name_conflict(u_long address)
{
//PK 2004/10/09 - 10/14
char buf[BUFSIZE];
buf[BUFLEN] = '\0';
int len = write_msg_head_to_buf(flag_name_conflict, buf, 0);
return _p2p_message(buf, len, address);
}
bool CSender::is_name_conflict(const string & username)
{ //PK 2004/10/09 - 23
users_type::iterator pos = m_users.begin();
users_type::iterator end = m_users.end();
for (; pos != end; ++pos)
if ((pos->second.user_name == username) && (username != m_myname)) return true;
return false;
}
void CSender::update_users()
{ //PK 2004/09/13 - 10/25
//PK update users. send a msg to every user, if can't receive a user's reply 3 times, kill him.
online();
_my_time now;
users_type::iterator pos = m_users.begin();
users_type::iterator end = m_users.end();
for (; pos != end; ++pos) {
if ((pos->second).is_online && (now - ((pos->second).last_online) > g_online_interval * 5)) {
m_pwindow->someone_logout(pos->first);
(pos->second).is_online = false;
}
}
}
void CSender::update_tasks()
{ //PK 2004/10/18 - 12/17
DEBUG_INFO("开始更新任务!\n")
DEBUG_INFO("有") DEBUG_INFO(m_recv_file_tasks.size()) DEBUG_INFO("个接收任务!\n")
DEBUG_INFO("有") DEBUG_INFO(m_send_file_tasks.size()) DEBUG_INFO("个发送任务!\n")
_my_time now;
EnterCriticalSection(&m_locker.m_critical);
tasks_type::iterator pos = m_recv_file_tasks.begin(), end = m_recv_file_tasks.end();
for (; pos != end;) {
if (now - pos->second->start_time > g_task_life_time) pos = m_recv_file_tasks.erase(pos);
else ++pos;
}
pos = m_send_file_tasks.begin(), end = m_send_file_tasks.end();
for (; pos != end;) {
if (now - pos->second->start_time > g_task_life_time){
bool del = true;
_task_send_file::user_stats_type::iterator ipos = ((_task_send_file*)(pos->second))->users.begin();
_task_send_file::user_stats_type::iterator iend = ((_task_send_file*)(pos->second))->users.end();
for (; ipos != iend; ++ipos) {
if (ipos->second) {
del = false;
break;
}
}
if (del) {
_task_send_file * temp = (_task_send_file*)pos->second;
pos = m_send_file_tasks.erase(pos);
delete temp;
} else ++pos;
} else ++pos;
}
LeaveCriticalSection(&m_locker.m_critical);
DEBUG_INFO("任务更新完毕!\n")
}
string CSender::get_user_name(u_long addr)
{ //PK 2004/09/13 - 10/21
if (m_users.end() != m_users.find(addr)) return m_users[addr].user_name;
return _get_peer_name(addr);
}
string CSender::_get_peer_name(u_long addr)
{
//PK 2004/09/13 - 10/14
//PK get the mathine name by its address
m_addr_p2p.sin_addr.s_addr = addr;
string name;
char buf_name[NI_MAXHOST];
char buf_serv[NI_MAXSERV];
int res = getnameinfo((SOCKADDR*)&m_addr_p2p, sizeof(m_addr_p2p),
buf_name, NI_MAXHOST, buf_serv, NI_MAXSERV, NI_NAMEREQD);
if (0 == res) return name = strlwr(buf_name);
return name;
}
string CSender::get_full_name(u_long addr)
{ //PK 2004/09/13 - 10/21
if (m_users.end() != m_users.find(addr)) return m_users[addr].user_name + "[" + m_users[addr].machine_name + "]";
return string();
}
bool CSender::send_a_file(_task_send_file * task)
{ //PK 2004/10/15 - 20
char buf[BUFSIZE];
buf[BUFLEN] = '\0';
char * cpos;
int len = write_msg_head_to_buf(flag_send_file, buf, &cpos);
memcpy(cpos, &(task->task_id), sizeof(task->task_id));
cpos += sizeof(task->task_id);
memcpy(cpos, &(task->file_size), sizeof(task->file_size));
cpos += sizeof(task->file_size);
string file_name = _get_file_name(task->file_name.c_str());
strcpy(cpos, file_name.c_str());
len = cpos - buf + file_name.length() + 1;
_task_send_file::user_stats_type::iterator pos = task->users.begin();
_task_send_file::user_stats_type::iterator end = task->users.end();
for(; pos != end; ++pos) _p2p_message(buf, len, pos->first);
return true;
}
bool CSender::confirm_recv_a_file(_task_recv_file * task)
{ //2004/10/18 - 20
char buf[BUFSIZE];
buf[BUFLEN] = '\0';
char * pos;
int len = write_msg_head_to_buf(flag_confirm_recv_file, buf, &pos);
memcpy(pos, &(task->task_id), sizeof(task->task_id));
len += sizeof(task->task_id);
_p2p_message(buf, len, task->peer_addr);
return true;
}
bool CSender::reject_a_file(_task_recv_file * task)
{ //PK 2004/10/18 - 12/17
char buf[BUFSIZE];
buf[BUFLEN] = '\0';
char * pos;
int len = write_msg_head_to_buf(flag_reject_file, buf, &pos);
memcpy(pos, &(task->task_id), sizeof(task->task_id));
len += sizeof(task->task_id);
_p2p_message(buf, len, task->peer_addr);
EnterCriticalSection(&m_locker.m_critical);
_erase_a_task(m_recv_file_tasks, task);
LeaveCriticalSection(&m_locker.m_critical);
return true;
}
unsigned __stdcall CSender::listen_file_send_thread(void * para)
{ //PK 2004/10/18 - 21
//PK start listening
DEBUG_INFO("文件发送线程侦听开始!\n")
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == s) return 1;
SOCKADDR_IN addr;
addr.sin_addr.s_addr = m_myaddr;
addr.sin_family = AF_INET;
addr.sin_port = htons(stream_port_listen);
if (SOCKET_ERROR == bind(s, (LPSOCKADDR)&addr, sizeof(addr))) {
int erro = WSAGetLastError();
return 1;
}
if (0 != listen(s, 8)) return 1;
bool is_continue = true;
while (is_continue) {
SOCKADDR_IN peer_addr;
int addr_len = sizeof(peer_addr);
SOCKET recv_s = accept(s, (LPSOCKADDR)&addr, &addr_len);
if (INVALID_SOCKET == recv_s) continue;
//PK is the peer_addr in listening address list
DEBUG_INFO("侦听到发送文件的连接,起发送线程!\n")
::_beginthreadex(NULL, 0, send_file_thread, (void*)recv_s, 0, 0);
}
closesocket(s);
DEBUG_INFO("侦听文件发送线程结束!\n")
return 0;
}
unsigned __stdcall CSender::recv_file_thread(void * para)
{ //PK 2004/10/18 - 29
#define ERROR_JUDGE(cond, err) \
if (cond) { \
error = err; \
goto exit;}
HANDLE hfile = INVALID_HANDLE_VALUE;
SOCKET s = INVALID_SOCKET;
error_no error = err_non;
DEBUG_INFO("开始一个文件接收线程!\n")
_task_recv_file * task = (_task_recv_file*)para;
//PK create tcp connection
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ERROR_JUDGE((INVALID_SOCKET == s), err_create_socket)
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(stream_port_listen);
addr.sin_addr.s_addr = task->peer_addr;
ERROR_JUDGE((SOCKET_ERROR == connect(s, (LPSOCKADDR)&addr, sizeof(addr))), err_create_connect)
//PK send the task_id
ERROR_JUDGE((SOCKET_ERROR == send(s, (char*)(&(task->task_id)), sizeof(task->task_id), 0)), err_send_data)
//PK recv the fil
char buf[FILEBUFSIZE];
int res = 0;
DWORD left = task->file_size;
hfile = CreateFile(task->file_name.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
ERROR_JUDGE((INVALID_HANDLE_VALUE == hfile), err_create_file)
while (left > 0)
{
res = recv(s, buf, FILEBUFSIZE, 0);
ERROR_JUDGE((SOCKET_ERROR == res), err_recv_data)
DWORD write_len;
ERROR_JUDGE((!WriteFile(hfile, (LPCVOID)buf, (DWORD)res, &write_len, NULL)), err_write_file)
left -= res;
}
exit:
if (INVALID_HANDLE_VALUE != hfile) CloseHandle(hfile);
if (INVALID_SOCKET != s) closesocket(s);
task->state = _task::complete;
_complete_recv_file(task, error);
DEBUG_INFO("文件接收完毕,接收线程终止!\n")
return 0;
}
unsigned __stdcall CSender::send_file_thread(void * para)
{ //PK 2004/10/18 - 12/17
DEBUG_INFO("开始文件发送线程!\n")
SOCKET s = (SOCKET)para;
SOCKADDR_IN addr;
int addr_len = sizeof(addr);
if (SOCKET_ERROR == getpeername(s, (LPSOCKADDR)&addr, &addr_len)) return 1;
//PK get the task_id
u_long task_id;
int res = recv(s, (char*)&task_id, sizeof(u_long), 0);
EnterCriticalSection(&m_locker.m_critical);
if (m_send_file_tasks.end() == m_send_file_tasks.find(task_id)) {
_task_is_canceled(task_id, addr.sin_addr.s_addr);
closesocket(s);
return 1;
}
_task_send_file * task = (_task_send_file*)m_send_file_tasks[task_id];
LeaveCriticalSection(&m_locker.m_critical);
//PK open file
HANDLE hfile = CreateFile(task->file_name.c_str(), GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hfile) return 1;
//PK send file (this function require winnt, win2k and winxp, and later.)
BOOL bres = TransmitFile(s, hfile, 0, 0, NULL, NULL, TF_USE_DEFAULT_WORKER);
CloseHandle(hfile);
closesocket(s);
_my_time now;
string message = g_system_info + " (" + now.get_time() + ") 发送文件 " + _get_file_name(task->file_name) +
" 给 " + get_user_name(addr.sin_addr.s_addr) + "完成!";
m_pwindow->someone_talk(message);
task->state = _task::prepare;
_erase_a_send_user(task, addr.sin_addr.s_addr);
DEBUG_INFO("文件发送完毕,发送线程终止!\n")
return 0;
}
bool CSender::_complete_recv_file(_task_recv_file * task, error_no err)
{ //PK 2004/10/18 - 12/17
_my_time now;
string message = g_system_info + "(" + now.get_time() + ") ";
if (err = err_non) message += get_user_name(task->peer_addr) + " 发送的文件 " + task->file_name + " 已经接收完成!";
else message += "接收 " + get_user_name(task->peer_addr) + " 发送的文件 " + task->file_name + " 时出现了以下错误:" + get_err_text(err) + "!";
m_pwindow->someone_talk(message);
EnterCriticalSection(&m_locker.m_critical);
_erase_a_task(m_recv_file_tasks, task);
LeaveCriticalSection(&m_locker.m_critical);
return true;
}
_task_send_file * CSender::add_a_send_file_task(CRStr fname, addresses_type & users)
{ //PK 2004/10/15 - 12/17
_task_send_file * task = new _task_send_file;
task->file_name = fname;
HANDLE hfile = CreateFile(fname.c_str(), GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hfile) return 0;
task->file_size = GetFileSize(hfile, NULL);
CloseHandle(hfile);
task->state = _task::prepare;
addresses_type::iterator pos = users.begin(), end = users.end();
for (; pos != end; ++pos) task->users[*pos] = false;
task->users.erase(m_myaddr);
EnterCriticalSection(&m_locker.m_critical);
m_send_file_tasks[task->task_id] = task;
LeaveCriticalSection(&m_locker.m_critical);
return task;
}
_task_recv_file * CSender::add_a_recv_file_task(u_long id, CRStr fname, DWORD file_size, u_long addr)
{ //PK 2004/10/18 - 12/17
_task_recv_file * task = new _task_recv_file;
task->task_id = id;
task->file_name = fname;
task->file_size = file_size;
task->peer_addr = addr;
task->state = _task::prepare;
EnterCriticalSection(&m_locker.m_critical);
m_recv_file_tasks[task->task_id] = task;
LeaveCriticalSection(&m_locker.m_critical);
return task;
}
bool CSender::is_task_exist(u_long task_id)
{ //PK 2004/10/27 - 12/17
EnterCriticalSection(&m_locker.m_critical);
bool bRes = m_recv_file_tasks.end() != m_recv_file_tasks.find(task_id) ||
m_send_file_tasks.end() != m_send_file_tasks.find(task_id);
LeaveCriticalSection(&m_locker.m_critical);
return bRes;
}
bool CSender::_erase_a_task(tasks_type & tasks, _task * task)
{ //PK 2004/10/18 - 20
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -