⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 局域网内聊天传输文件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -