Hello,今天小编给大家带来一个用Visual studio编写的聊天室项目, 此聊天室使用tcp/IP 传输信息,采用socket 和MFC 两个框架。
项目名称:凤凰聊天室
项目目的:实现在不同客户端之间传输信息和txt文件。在最终实现过程中需使用内网穿透来让在不同局域网内的客户端实现通信
创建项目的主要思想:
我们需要客户端和服务端两个端来实现这一聊天室。
客户端将数据通过指定端口传给指定服务器(一般来说就是一台电脑),服务器一旦受到请求,通过开启多个线程来同时与多个客户端进行通讯, 并将收到的数据附送给所有与服务器连接的客户端。
由于需要实现不同局域网之间的通讯,需要实现内网穿透,具体教程按照我的另一篇文章
项目实现:
首先先上几个之后需要用的头文件
附上下载地址(用MFC界面):
Multichatroom下载
https://download.csdn.net/download/qq_42662283/12488515
写码不易,如果觉得从代码里学到一些知识,关注收藏一下呗,为小编鼓励一下,谢谢!!!
第二篇文章(客户端实现)
https://blog.csdn.net/qq_42662283/article/details/106493781
FileUtil.h
#pragma once
#include <stdio.h>
#include <WINSOCK2.H>
#include <io.h>
#include <string>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
class FileUtil
{
private:
FILE *f;
public:
FILE * openFile(CString filename)
{
char* name = CString2Char(filename);
if (f = fopen(name, "r"))
{
printf("文件打开成功\n");
return f;
}
else
{
printf("文件不存在\n");
return NULL;
}
}
FILE * createFile(char *name)
{
//创建一个空的文件,若有同名文件存在则将内容删除
if (f = fopen(name, "w"))
{
printf("文件创建成功\n");
}
else
{
printf("文件创建失败\n");
}
return f;
}
bool createDir(char *dir)
{
char head[MAX_PATH] = "md ";
return system(strcat(head, dir));
}
char* CString2Char(CString string)
{
int n = string.GetLength(); //获取str的字符数
char *pChar = new char[n + 1]; //以字节为单位
WideCharToMultiByte(CP_ACP, 0, string, n, pChar, n + 1, NULL, NULL); //宽字节编码转换成多字节编码
pChar[n] = '\0'; //多字节字符以'\0'结束
return pChar;
}
char* string2Char(string string)
{
return (char *)string.data();
}
};
Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 Client.rc 使用
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_CLIENT_DIALOG 102
#define IDR_MAINFRAME 128
#define IDC_EDIT_Message 1000
#define IDC_EDIT_IP 1001
#define IDC_EDIT_Port 1003
#define IDC_BT_LogIn 1006
#define IDC_EDIT_Name 1009
#define IDC_BT_LogOut 1010
#define IDC_EDIT_SendText 1011
#define IDC_BT_Send 1012
#define IDC_BT_CLEAR 1013
#define IDC_BT_FILE 1015
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 133
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1016
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#ifndef _SECURE_ATL
#define _SECURE_ATL 1
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdisp.h> // MFC Automation classes
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h> // MFC support for ribbons and control bars
#ifdef _UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
targetver.h
#pragma once
//定义最高级别的windows平台
#include <SDKDDKVer.h>
客户端实现(头文件(如果编译需要包含之前的四个头文件)):
!!!这里只有头文件,源码请看第二期
Client_LAN.h
// Client.h : main header file for the PROJECT_NAME application
//
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
// CClientApp:
// See Client.cpp for the implementation of this class
//
class CClientApp : public CWinApp
{
public:
CClientApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CClientApp theApp;
ClientCon_LAN.h
#pragma once
#include "string"
#include <winsock2.h>
#include <stdio.h>
#include "FileUtil.h"
using namespace std;
class CClientDlg;
class ClientCon
{
public:
ClientCon(CClientDlg *dlg);
~ClientCon(void);
void StartConnect(string sAddress, int iPort, string sUsername);
void SendData(string sMessage, bool showName = false);
void SendFile(FILE* file, CString filename);
WSADATA wsa;
SOCKET sClient;
CClientDlg *m_pClient;
string m_pUser;
bool isFile;//接收方用于控制是否接受文件
bool isReady;//发送方用于控制是否继续发送文件
FileUtil fu;
FILE * file;
};
ClientDlg_LAN.h
// ClientDlg.h : header file
//
#pragma once
#include "stdafx.h"
#include "resource.h"
#include <string>
#include "ClientCon_LAN.h"
// CClientDlg dialog
class CClientDlg : public CDialogEx
{
// Construction
public:
CClientDlg(CWnd* pParent = NULL); // standard constructor
void ShowServerInfo(string sValue);
// Dialog Data
enum { IDD = IDD_CLIENT_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// 实现
protected:
HICON m_hIcon;
// 迭代message map
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP();
public:
ClientCon *m_pClient;
static UINT __cdecl StaticThreadFunc(LPVOID pParam);
UINT ThreadFunc();
void AppendTextToEditCtrl(CEdit& edit, LPCTSTR pszText);
CEdit m_Portbox;
private:
HANDLE m_Thread_handle;
CWinThread *cTh;
public:
CEdit m_Textbox;
afx_msg void OnBnClickedOk();
afx_msg void OnClickedBtLogin();
afx_msg void OnClickedBtLogout();
afx_msg void OnClickedBtSend();
afx_msg void OnClickedBtClear();
afx_msg void OnClickedBtFile();
//在系统之前截获按键信息
virtual BOOL PreTranslateMessage(MSG* pMsg);
};
服务端实现(头文件(如果编译需要包含之前的四个头文件)):
!!!这里只有头文件,源码请看第二期
Server_LAN.h
// Server.h : main header file for the PROJECT_NAME application
//
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
#include <string.h>
#include <string>
using namespace std;
// CServerApp:
// See Server.cpp for the implementation of this class
//
class CServerApp : public CWinApp
{
public:
CServerApp();
// Overrides
public:
virtual BOOL InitInstance();
static void OnServerAction(std::string sValue);
// Implementation
DECLARE_MESSAGE_MAP()
};
extern CServerApp theApp;
ServerDlg.h
#pragma once
#include "ServerManager_LAN.h"
#include <Windows.h>
// CServerDlg dialog
class CServerDlg : public CDialogEx
{
// Construction
public:
CServerDlg(CWnd* pParent = NULL); // standard constructor
void ShowServerInfo(string sValue);
// Dialog Data
enum { IDD = IDD_SERVER_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CString m_buffer;
CEdit m_Textbox;
afx_msg void OnBnClickedCancel();
afx_msg void OnBnClickedOk();
afx_msg void OnClickedBtStart();
afx_msg void OnClickedBtStop();
ServerManager *m_pServer;
static UINT __cdecl StaticThreadFunc(LPVOID pParam);
UINT ThreadFunc();
void AppendTextToEditCtrl(CEdit& edit, LPCTSTR pszText);
CEdit m_Portbox;
private:
HANDLE m_Thread_handle;
CWinThread *cTh;
public:
afx_msg void OnClickedBtClear();
};
ServerManager_LAN.h
#pragma once
#include<winsock2.h>
class CServerDlg;
#pragma comment(lib,"ws2_32.lib")
class ServerManager
{
public:
ServerManager(CServerDlg* dialog);
~ServerManager(void);
WSADATA wsa;
SOCKET s , new_socket;
//static SOCKET sArray[100];
struct sockaddr_in server , client;
int c;
//static int iCount;
int iTempCount;
CServerDlg* m_pDialog;
HANDLE m_Thread_handle[100];
CWinThread *cpTh[100];
static void SetStaticVariable(int iC, SOCKET cS);
void StartListening(int iPort);
static UINT __cdecl DataThreadFunc(LPVOID pParam);
UINT SendReceiveData(SOCKET cSocket);
void ClearServer();
};
第二篇文章(客户端实现)
https://blog.csdn.net/qq_42662283/article/details/106493781