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

📄 chatdlg.cpp

📁 基于TCP的局域网多用户通信、文件传送程序详解
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ChatDlg.cpp : implementation file
//

#include "stdafx.h"
#include "wbQQClient.h"
#include "ChatDlg.h"

#include "CarryFile.h"
#include "AboutAuth.h"

#define NO_FLAGS_SET 0
#define MAXBUFLEN 5025
#define WM_SYSTEMTRAY WM_USER + 1
#define WM_RECVDATA WM_USER + 2

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

HWND recvWnd;
CWinThread *pSendFile;
//////////////////////////////全局函数获取SOCKET错误详细信息/////////////////
CString GetError(DWORD error)
{
	CString strError;
	switch(error)
	{
	case WSANOTINITIALISED:
		strError="初始化错误";
		break;
	case WSAENOTCONN:
		strError="对方没有启动";
		break;
	case WSAEWOULDBLOCK :
		strError="对方已经关闭";
		break;
	case WSAECONNREFUSED:
		strError="连接的尝试被拒绝";
		break;
	case WSAENOTSOCK:
		strError="在一个非套接字上尝试了一个操作";
		break;
	case WSAEADDRINUSE:
		strError="特定的地址已在使用中";
		break;
	case WSAECONNRESET:
		strError="与主机的连接被关闭";
		break;
	default:
		strError="一般错误";	
	}
	return strError;	
}
///////////////////////接收文件线程(客户端模式)////////////////////////////
UINT recvFile(void *data)
{
	char nameIP[40];
	strcpy(nameIP, (char*)data);
	char name[20];
	char IP[20];
	for (int i=0; nameIP[i]!='~'; i++)
	{
		name[i] = nameIP[i];
	}
	name[i++] = '\0';	//获得发送者用户名
	strcpy(IP, nameIP + i);	//获得发送者IP地址
	CString strCaption = name;
	strCaption += "  传来文件";
	CCarryFile dlg;
	dlg.m_strCaption = strCaption;
	strcpy(dlg.m_destIP, IP);
	dlg.DoModal();

	ExitThread(0);
	return 0;
}
///////////////////////发送文件线程(服务器模式)/////////////////////////////
UINT sendFile(void *name)
{
	char destName[20];
	strcpy(destName, (char*)name);
	CString strCaption = "传送文件给  ";
	strCaption += destName;
	CCarryFile dlg;
	dlg.m_strCaption = strCaption;
	dlg.m_bSendFile = true;
	dlg.DoModal();

	return 1;
}
/////////////////////////////////////////////////////////////////////////////
// CChatDlg dialog
UINT RecvThread(void* cs)
{
	char buffer[MAXBUFLEN] = {0};
	int numrcv;
	SOCKET clientSocket = (SOCKET)cs;
	while (1)
	{
		numrcv = recv(clientSocket, buffer, MAXBUFLEN, NO_FLAGS_SET);
		if ((numrcv == 0) || (numrcv == SOCKET_ERROR))
		{
			AfxMessageBox("RecvThread:Connection terminated!\n"
				+ GetError(GetLastError()), MB_OK);
			break;
		}
		buffer[numrcv] = '\0';
		char type[10];		//判断接收到的消息种类
		for (int i=0; i<9; i++)
		{
			type[i] = buffer[i];
		}
		type[9] = '\0';	//"SendFile!"有9个字符
		if (strcmp(type, "SendFile!") == 0)		//对方要给我发送文件
		{
			char senderName[20];
			for (i=0; buffer[i+9]!='~'; i++)
			{
				senderName[i] = buffer[i+9];
			}
			senderName[i] = '\0';
			char str[80];
			strcpy(str, senderName);
			strcat(str, "   想给你发送文件!\n接收按“是”,拒绝按“否”");
			if (AfxMessageBox(str, MB_YESNO) == IDYES)
			{
				AfxBeginThread(recvFile, (LPVOID*)(buffer+9));	//开始接收文件线程
			}
			else
			{
				CString strRefuse;
				strRefuse = senderName;
				strRefuse += ":";
				strRefuse += "Refuse!";
				send(clientSocket, strRefuse, strRefuse.GetLength(), 0);//发送拒收文件消息
			}
			continue;
		}
		type[7] = '\0';	//"Refuse!"有7个字符
		if (strcmp(type, "Refuse!") == 0)	//对方拒绝接收文件
		{
			AfxMessageBox("对方拒绝接收文件!\n按取消关闭对话框。", MB_OK);
			TerminateThread(pSendFile, 0);
			continue;
		}
		::PostMessage(recvWnd, WM_RECVDATA, DWORD((LPSTR)buffer), numrcv);//普通消息
	}
	closesocket(clientSocket);
	return 1;
}

CChatDlg::CChatDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CChatDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChatDlg)
	m_strCity = _T("");
	m_strRecv = _T("");
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


void CChatDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChatDlg)
	DDX_Control(pDX, IDC_BTN_MORE, m_more);
	DDX_Control(pDX, IDC_STATIC_PIC, m_pic);
	DDX_Control(pDX, IDC_COMBO_PETNAME, m_petname);
	DDX_Control(pDX, IDC_FRIEND, m_friend);
	DDX_Control(pDX, IDC_EDIT_MESSAGE, m_message);
	DDX_Text(pDX, IDC_EDIT_CITY, m_strCity);
	DDX_Text(pDX, IDC_EDIT_RECEIVE, m_strRecv);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CChatDlg, CDialog)
	//{{AFX_MSG_MAP(CChatDlg)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BTN_MORE, OnBtnMore)
	ON_BN_CLICKED(IDC_BTN_SEND, OnBtnSend)
	ON_BN_CLICKED(IDC_BTN_REPLY, OnBtnReply)
	ON_CBN_SELCHANGE(IDC_COMBO_PETNAME, OnSelchangeComboPetname)
	ON_COMMAND(ID_ABOUT, OnAbout)
	ON_COMMAND(ID_CLOSE, OnClose)
	ON_COMMAND(ID_SHOW, OnShow)
	ON_BN_CLICKED(IDC_BTN_CARRY_FILE, OnBtnCarryFile)
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_RECVDATA, RecvData)
	ON_MESSAGE(WM_SYSTEMTRAY, OnSystemTray)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChatDlg message handlers

BOOL CChatDlg::InitNet()
{
	char IP[20];	//用于从网络设置文件读取IP地址
	char port[8];	//用于从网络设置文件读取字符串端口号
	u_short nPort;
	FILE *pFile;
	CString cfgFileName;
	cfgFileName.Format(".\\data\\netset.cfg");
	pFile = fopen(cfgFileName, "r");
////////////////从网络设置文件读取聊天通信服务器IP地址////////////////
	char ch = 's';
	for (int i=0; ch != ','; i++)
	{
		ch = fgetc(pFile);
	}
	ch = 's';
	for (i=0; ch != ','; i++)
	{
		ch = fgetc(pFile);
	}
	ch = 's';
	for (i=0; ch != ','; i++)	//ch已定位到聊天通信服务器IP地址
	{
		ch = fgetc(pFile);
		IP[i] = ch;
	}
	IP[--i] = '\0';
////////////////从网络设置文件读取聊天通信服务器端口///////////////////
	ch = 's';
	for (i=0; !feof(pFile); i++)
	{
		ch=fgetc(pFile);
		port[i] = ch;
	}
	port[--i] = '\0';
	nPort = atoi(port);

	fclose(pFile);
//////////////////初始化ws2_32.dll动态库,创建套接字///////////////////
	status = WSAStartup(MAKEWORD(1, 1), &Data);
	if (status != 0)
	{
		MessageBox("ERROR: WSAStartup unsuccessfull!" + GetError(GetLastError()),
			"闻博QQ", MB_OK);
	}
	destAddr = inet_addr(IP);
	memcpy(&destSockAddr.sin_addr, &destAddr, sizeof (destAddr));
	destSockAddr.sin_port = htons(nPort);
	destSockAddr.sin_family = AF_INET;
	destSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (destSocket == INVALID_SOCKET)
	{
		MessageBox("ERROR:socket unsccessful!" + GetError(GetLastError()),
			"闻博QQ", MB_OK);
		status = WSACleanup();
		if (status == SOCKET_ERROR)
		{
			MessageBox("ERROR:WSACleanup unsccessful!" + GetError(GetLastError()),
				"闻博QQ", MB_OK);
		}
		return false;
	}

	status = connect(destSocket, (LPSOCKADDR)&destSockAddr, sizeof(destSockAddr));
	if (status == SOCKET_ERROR)
	{
		MessageBox("ERROR:connect unsccessful!" + GetError(GetLastError()),
			"闻博QQ", MB_OK);
		status = closesocket(destSocket);
		if (status == SOCKET_ERROR)
		{
			MessageBox("ERROR:closesocket unsccessful!" + GetError(GetLastError()),
				"闻博QQ", MB_OK);
		}
		status = WSACleanup();
		if (status == SOCKET_ERROR)
		{
			MessageBox("ERROR:WSACleanup unsccessful!" + GetError(GetLastError()),
				"闻博QQ", MB_OK);
		}
		return false;
	}
	send(destSocket, m_strUserName, m_strUserName.GetLength(), 0);
	AfxBeginThread(RecvThread, (LPVOID)destSocket);

	return true;
}

void CChatDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	char temp[30];
	strcpy(temp, petname);
	strcat(temp, "的消息");

	if (!flag)
	{
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof (NOTIFYICONDATA);
		nid.hWnd = m_hWnd;
		nid.uID = ID_SYSTEMTRAY;
		nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
		nid.uCallbackMessage = WM_SYSTEMTRAY;
		nid.hIcon = AfxGetApp()->LoadIcon(m_nNetSel);
		strcpy(nid.szTip, temp);
		::Shell_NotifyIcon(NIM_MODIFY, &nid);
		m_pic.SetIcon(AfxGetApp()->LoadIcon(m_nNetSel));
	}
	else
	{
		NOTIFYICONDATA nid;
		nid.cbSize = sizeof (NOTIFYICONDATA);
		nid.hWnd = m_hWnd;
		nid.uID = ID_SYSTEMTRAY;
		nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
		nid.uCallbackMessage = WM_SYSTEMTRAY;
		nid.hIcon = AfxGetApp()->LoadIcon(IDI_NULL);
		strcpy(nid.szTip, temp);
		::Shell_NotifyIcon(NIM_MODIFY, &nid);
		m_pic.SetIcon(AfxGetApp()->LoadIcon(IDI_NULL));
	}
	flag = !flag;
	
	CDialog::OnTimer(nIDEvent);
}

LRESULT CChatDlg::OnSystemTray(WPARAM wParam, LPARAM lParam)
{
	BringWindowToTop();
	if (wParam == ID_SYSTEMTRAY)
	{
		switch (lParam)
		{
		case WM_LBUTTONDBLCLK:
			{
				KillTimer(0);
				NOTIFYICONDATA nid;
				nid.cbSize = sizeof(NOTIFYICONDATA);
				nid.hWnd = m_hWnd;
				nid.uID = ID_SYSTEMTRAY;
				nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
				nid.uCallbackMessage = WM_SYSTEMTRAY;
				nid.hIcon = AfxGetApp()->LoadIcon(res);
				strcpy(nid.szTip, ("闻博QQ:" + m_strUserName));
				::Shell_NotifyIcon(NIM_MODIFY, &nid);
				::ShowWindow(m_hWnd, SW_SHOWDEFAULT);
				m_pic.SetIcon(AfxGetApp()->LoadIcon(res));
			}
			break;
		case WM_RBUTTONDOWN:
			{
				CMenu menu;
				menu.LoadMenu(IDR_MENU1);
				CMenu *pMenu = menu.GetSubMenu(0);
				ASSERT(pMenu != NULL);
				CPoint point;
				GetCursorPos(&point);
				pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
					point.x, point.y, this);
				PostMessage(WM_NULL);
			}
			break;
		default:
			break;
		}
	}
	return 1;
}

BOOL CChatDlg::DestroyWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	CString close = "Close!";
	send(destSocket, close, close.GetLength(), 0);
////////////////////////////////////////////////////////////////////////
	NOTIFYICONDATA nid;
	nid.cbSize = sizeof (NOTIFYICONDATA);

⌨️ 快捷键说明

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