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

📄 main.cpp

📁 局域网内聊天传输文件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
  取之于斯,用之于斯。
  我自己的学习成长,有一大部分要归功于在互联网上接触到的一些开源的代码和开源项目。作者的精湛技艺,尤其是他们博大的胸怀,让我敬仰不已。
  因此我也将自己写的一些代码及工具,只要是比较完整的,不涉及到工作中保密信息的,整理出来。放到网上,希望能对其他人有用。
  你可以自由的拷贝,分发,使用这些代码,最好是能提到它的出处,我保留除此之外的所有权利。由于是非商业性的软件及代码,在使用过程中造成的所有损失,我不承担任何责任。 :)
  我的邮件:pankkk@hotmail.com
  我的名字:潘凯
  欢迎和我交流技术方面的问题。


  我已经发布的一些代码及工具。这些代码及工具我一般发布在vchelp及vccode的论坛上,这两个地方是我常去的地方,只是近来都是潜水,很少发言。:)

1、一个从codeproject下载文章及源码的工具,可以将上面所有的文章及源码都下载到本机,并保留原来的分类信息,去掉页面上的广告。发布日期2003/1
  这个软件是用MFC做的。现在可能已经不能用了,因为当时不用登录也可以下载源码,现在必须要是会员,而且要登录后才能下载。而且网站的组织结构也变了。有兴趣的朋友可以自己试着改源码。

2、一个上网计时的小软件。发布时期2003/11
  这个软件主要也是自用,当时家里办了ADSL上网,一个月60小时。当时下了一些计时软件,感觉不好用,功能太多,就自己写了一个。界面比较简陋,但也够用了。

3、一个点对点的局域网聊天软件,有QQ的Emotion功能,可以一对多的传文件。发布日期2004/12,发布版本1.13。
  界面部分用WTL做的,聊天用UDP协议,传文件是TCP协议。由于不需要服务器,很多功能实现起来还是很麻烦的。

*/


#include "stdafx.h"
#include <ws2tcpip.h>
#include <Mswsock.h>

#include "main.h"

#define NI_MAXHOST  1025
#define NI_MAXSERV    32

#ifdef _DEBUG
//PK for test
const int dgram_port = 50132;
const char * str_dgram_port = "50132";
const int stream_port_listen = 21109;
#else
//PK for release
const int dgram_port = 50131;
const char * str_dgram_port = "50131";
const int stream_port_listen = 21108;
#endif

static unsigned __stdcall
thread_receiver(void *);

SOCKADDR_IN			CSender::m_addr_brat;
SOCKADDR_IN			CSender::m_addr_p2p;
SOCKADDR_IN			CSender::m_addr_recv;
SOCKET				CSender::m_sock_recv;
SOCKET				CSender::m_sock_send;
CSender::users_type	CSender::m_users;
CSender::users_type CSender::m_blacklist;
string				CSender::m_myname;
CMainDlg*			CSender::m_pwindow = NULL;
u_long				CSender::m_myaddr = 0;
u_long				CSender::m_conflict_addr = 0;
tasks_type			CSender::m_send_file_tasks;
tasks_type			CSender::m_recv_file_tasks;
fstream				CSender::m_history("history.dat", std::ios_base::out | std::ios_base::app);
#ifdef _DEBUG
fstream				CSender::m_log("log.dat", std::ios_base::out);
#endif
CLock				CSender::m_locker;

void start_receive(void * revc_handler)
{	//PK 2004/08/31 - 10/21
	_beginthreadex(NULL, 0, CSender::thread_receiver, revc_handler, 0, 0);
	_beginthreadex(NULL, 0, CSender::listen_file_send_thread, 0, 0, 0);
}

bool CSender::start()
{	//PK 2004/09/10 - 10/20
	m_addr_recv.sin_family = AF_INET;
	m_addr_recv.sin_port = htons(dgram_port);
	m_addr_recv.sin_port = dgram_port;
	m_addr_brat = m_addr_recv;
	m_addr_p2p = m_addr_recv;

	//PK broadcast address
	m_addr_brat.sin_addr.s_addr = inet_addr("192.0.3.255");

	//PK get locol ip address for receive
	//PK get local name
	char hostname[125];
	if (0 != gethostname(hostname, 124)) return false;
	//PK get local ip
	ADDRINFO hints, *res = NULL, *ptr = NULL;
	int count = 0, rc;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	hints.ai_protocol = IPPROTO_UDP;
	hints.ai_flags = AI_CANONNAME;
	rc = getaddrinfo(hostname, str_dgram_port, &hints, &res);
	if (0 != rc) return false;
	m_addr_recv.sin_addr.s_addr = ((SOCKADDR_IN*)res->ai_addr)->sin_addr.s_addr;
	freeaddrinfo(res);

	m_myaddr = m_addr_recv.sin_addr.s_addr;

	m_sock_recv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (INVALID_SOCKET == m_sock_recv) return false;
	if (0 != bind(m_sock_recv, (SOCKADDR*)&m_addr_recv, sizeof(m_addr_recv))) return false;

	m_sock_send = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (INVALID_SOCKET == m_sock_send) return false;

	return true;
}

bool CSender::close()
{
//PK 2004/09/10
	closesocket(m_sock_recv);
	closesocket(m_sock_send);
	return true;
}

unsigned __stdcall CSender::thread_receiver(void * argu)
{	//PK 2004/08/31 - 10/25
	//PK receive thread
	m_pwindow = (CMainDlg*)argu;

	SOCKADDR_IN sender_addr;
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';

	for (;;) {
		//PK receive a msg
		int sender_addr_len = sizeof(sender_addr);
		int recv_len = recvfrom(m_sock_recv, buf, BUFLEN, 0, (SOCKADDR*)&sender_addr, &sender_addr_len);
		if (recv_len < HEADSIZE) continue;

		_msg_head * msg_head = (_msg_head*)buf;
		char * msg_body = buf + HEADSIZE;

		//PK identify the mask 
		if (msg_head->mask != g_mask) continue;
		bool is_old_version = false;
		if (_is_newest_version(msg_head->version)) is_old_version = true;

		u_long addr = (u_long)(u_long)sender_addr.sin_addr.s_addr;
		bool is_in_blacklist = false;
		if (m_blacklist.end() != m_blacklist.find(addr)) is_in_blacklist = true;
		
		//string peer_name = _get_peer_name(addr);
		switch (msg_head->flag) {
		case flag_login:
			on_login(msg_head, msg_body, addr);
			break;
		case flag_logout:
			on_logout(msg_head, msg_body, addr);
			break;
		case flag_online:
			on_online(msg_head, msg_body, addr);
			break;
		case flag_say:
			if (is_in_blacklist) break;
			on_say(msg_head, msg_body, addr);
			break;
		case flag_whisper:
			if (is_in_blacklist) break;
			if (addr != m_myaddr) on_whisper(msg_head, msg_body, addr);
			break;
		case flag_rename:
			if (is_in_blacklist) break;
			if (addr != m_myaddr) on_rename(msg_head, msg_body, addr);
			break;
		case flag_name_conflict:
			if (is_in_blacklist) break;
			on_name_conflict(msg_head, msg_body, addr);
			break;
		case flag_send_file:
			if (is_in_blacklist) break;
			if (addr != m_myaddr) on_recv_file(msg_head, msg_body, addr);
			break;
		case flag_confirm_recv_file:
			on_confirm_recv_file(msg_head, msg_body, addr);
			break;
		case flag_reject_file:
			on_reject_file(msg_head, msg_body, addr);
			break;
		case flag_task_cancel:
			on_task_cancel(msg_head, msg_body, addr);
			break;
		case flag_emotion:
			on_emotion(msg_head, msg_body, addr);
			break;
		}
	}
	return 0;
}

bool CSender::_broadcast_message(CPChar buf, int len)
{
//PK 2004/08/31 - 10/14
//PK broadcast a message
	int res = sendto(m_sock_send, buf, len, 0, (SOCKADDR*)&m_addr_brat, sizeof(m_addr_brat));
	return res != SOCKET_ERROR;
}

bool CSender::_p2p_message(const char * buf, int len, u_long addr)
{
//PK 2004/09/13 - 10/14
//PK send a message by peer2peer
	m_addr_p2p.sin_addr.s_addr = addr;
	int res = sendto(m_sock_send, buf, len, 0, (SOCKADDR*)&m_addr_p2p, sizeof(m_addr_p2p));
	return res != SOCKET_ERROR;
}

bool CSender::_send_message_to_all(CPChar buf, int len)
{	//PK 2004/10/14
	users_type::iterator pos = m_users.begin();
	users_type::iterator end = m_users.end();
	for (; pos != end; ++pos) {
		bool res = _p2p_message(buf, len, pos->first);
		if (!res) return false;
	}
	return true;
}
bool CSender::login()
{
//PK 2004/09/01 - 10/14
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_login, buf, &pos);
	strcpy(pos, get_myname().c_str());
	len += get_myname().length() + 1;
	return _broadcast_message(buf, len);
}

bool CSender::logout()
{
//PK 2004/09/13 - 10/14
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';
	int len = write_msg_head_to_buf(flag_logout, buf, 0);
	return _broadcast_message(buf, len);
}

bool CSender::online(u_long addr)
{	//PK 2004/10/14
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_online, buf, &pos);
	strcpy(pos, get_myname().c_str());
	len += get_myname().length() + 1;
	return _p2p_message(buf, len, addr);
}
bool CSender::online()
{	//PK 2004/10/14
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_online, buf, &pos);
	strcpy(pos, get_myname().c_str());
	len += get_myname().length() + 1;
	return _send_message_to_all(buf, len);
}
bool CSender::said_to_all(CRStr data)
{
//PK 2004/08/31 - 10/14
	char buf[BUFSIZ];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_say, buf, &pos);
	strcpy(pos, data.c_str());
	len += data.length() + 1;
	return _send_message_to_all(buf, len);
}

bool CSender::whisper(CRStr data, u_long addr)
{	//PK 2004/09/13 - 2004/10/14
	char buf[BUFSIZE];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_whisper, buf, &pos);
	strcpy(pos, data.c_str());
	len += data.length() + 1;
	return _p2p_message(buf, len, addr);
}
bool CSender::rename(const string& username)
{	//PK 2004/10/09 - 10/14
	char buf[BUFSIZE];
	buf[BUFLEN] = '\0';
	char * pos;
	int len = write_msg_head_to_buf(flag_rename, buf, &pos);
	strcpy(pos, username.c_str());
	len += username.length() + 1;
	bool result = _send_message_to_all(buf, len);
	if (!result) return false;
	m_myname = username;
	m_conflict_addr = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -