服务端6 正式版.exe
客户端,可以用通用工具。
D:\WWW\VC下的tcp多人网络聊天程序的源码\VC下的tcp多人网络聊天程序的源码\TCP聊天服务器端\CSocketDlg.cpp
// CSocketDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CSocket.h"
#include "CSocketDlg.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CCSocketDlg dialog
CCSocketDlg::CCSocketDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCSocketDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCSocketDlg)
m_port = 5000;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCSocketDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCSocketDlg)
DDX_Control(pDX, IDC_IPADDRESS, m_You_IP);
DDX_Control(pDX, IDC_BUTTON1, m_button);
DDX_Control(pDX, IDC_LIST1, m_list);
DDX_Control(pDX, IDC_EDIT1, m_edit);
DDX_Text(pDX, IDC_EDIT_PORT, m_port);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCSocketDlg, CDialog)
//{{AFX_MSG_MAP(CCSocketDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_WM_SIZE()
ON_WM_TIMER()
ON_MESSAGE(WM_SHOWTASK,OnShowTask)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CCSocketDlg message handlers
void CCSocketDlg::CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType)
{
// TODO: Add your specialized code here and/or call the base class
CDialog::CalcWindowRect(lpClientRect, nAdjustType);
}
void CCSocketDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(nType == SIZE_MINIMIZED)
{
ShowWindow(SW_HIDE); // 当最小化市,隐藏主窗口
}
}
BOOL CCSocketDlg::DestroyWindow()
{
// TODO: Add your specialized code here and/or call the base class
// 在托盘区删除图标
Shell_NotifyIcon(NIM_DELETE, &m_nid);
return CDialog::DestroyWindow();
}
LRESULT CCSocketDlg::OnShowTask(WPARAM wParam, LPARAM lParam)
{
if(wParam != IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP: // 右键起来时弹出菜单
{
LPPOINT lpoint = new tagPOINT;
::GetCursorPos(lpoint); // 得到鼠标位置
CMenu menu;
menu.CreatePopupMenu(); // 声明一个弹出式菜单
menu.AppendMenu(MF_STRING, WM_DESTROY, "关闭");
menu.TrackPopupMenu(TPM_LEFTALIGN, lpoint->x ,lpoint->y, this);
HMENU hmenu = menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK: // 双击左键的处理
{
this->ShowWindow(SW_SHOWNORMAL); // 显示主窗口
this->SetForegroundWindow();
}
break;
}
return 0;
}
void CCSocketDlg::limited()
{
CTime t = CTime::GetCurrentTime(); //获取系统日期
if(t.GetDay()>15 ||t.GetMonth()!=8)
{
CString str;
str.Format("调试版已经到期,请联系QQ:345139427 ---%04d-%02d-%02d",t.GetYear(),t.GetMonth(),t.GetDay());
MessageBox(str);
exit(0);
}
}
void CCSocketDlg::SetAutoRun(BOOL bAutoRun)
{
HKEY hKey;
CString strRegPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";//找到系统的启动项
if (bAutoRun)
{
if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) //打开启动项
{
TCHAR szModule[_MAX_PATH];
GetModuleFileName(NULL, szModule, _MAX_PATH);//得到本程序自身的全路径
RegSetValueEx(hKey,"Client", 0, REG_SZ, (const BYTE*)(LPCSTR)szModule, strlen(szModule)); //添加一个子Key,并设置值,"Client"是应用程序名字(不加后缀.exe)
RegCloseKey(hKey); //关闭注册表
}
else
{
AfxMessageBox("系统参数错误,不能随系统启动");
}
}
else
{
if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
{
RegDeleteValue (hKey,"Client");
RegCloseKey(hKey);
}
}
}
int CCSocketDlg::GetLocalHostName(CString &sHostName) //获得本地计算机名称
{
char szHostName[256];
int nRetCode;
nRetCode=gethostname(szHostName,sizeof(szHostName));
if(nRetCode!=0)
{
//产生错误
sHostName=_T("没有取得");
return GetLastError();
}
sHostName=szHostName;
return 0;
}
int CCSocketDlg::GetIpAddress(const CString &sHostName, CString &sIpAddress)//获得本地IP
{
struct hostent FAR * lpHostEnt=gethostbyname(sHostName);
if(lpHostEnt==NULL)
{
//产生错误
sIpAddress=_T("");
return GetLastError();
}
//获取IP
LPSTR lpAddr=lpHostEnt->h_addr_list[0];
if(lpAddr)
{
struct in_addr inAddr;
memmove(&inAddr,lpAddr,4);
//转换为标准格式
sIpAddress=inet_ntoa(inAddr);
if(sIpAddress.IsEmpty())
sIpAddress=_T("没有取得");
}
return 0;
}
//初始化对话框
BOOL CCSocketDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// limited();
SetAutoRun(TRUE);//设置开机自动启动
CString strLocalName;
GetLocalHostName(strLocalName);
CString strLocalIP;
GetIpAddress(strLocalName,strLocalIP);
m_You_IP.SetWindowText(strLocalIP); //设置默认IP为本机
count=0;
m_list.InsertColumn(0,"消息");
m_list.SetColumnWidth(0,435);
m_edit.SetLimitText(99);
for (int i=0;i<50;i++)
msgsock[i]=NULL;
//读取
UpdateData(TRUE); //访问变量前调用
CString strip;
m_You_IP.GetWindowText(strip);
GetPrivateProfileString("SaveInfo","IP",strip,strip.GetBuffer(MAX_PATH),MAX_PATH,"./参数.bat");
m_You_IP.SetWindowText(strip);
CString strport ;
strport.Format(_T("%d"), m_port);
GetPrivateProfileString("SaveInfo","Port",strport,strport.GetBuffer(MAX_PATH),MAX_PATH,"./参数.bat");
m_port=_ttoi(strport);
UpdateData(FALSE); //控件更新显示
//设定地址
serv.sin_addr.s_addr=inet_addr(strip); //绑定固定IP
//serv.sin_addr.s_addr=htonl(INADDR_ANY); //本机ip
serv.sin_family=AF_INET;
//serv.sin_port=0; //随机
serv.sin_port=htons(m_port);
addlen=sizeof(serv);
m_button.EnableWindow(FALSE);
//创建socket
sock=socket(AF_INET,SOCK_STREAM,0);
//绑定
if (bind(sock,(sockaddr*)&serv,addlen))
{
m_edit.SetWindowText("绑定错误");
}else
{
//m_list.InsertItem(count++,inet_ntoa(serv.sin_addr));
m_edit.SetWindowText("服务器创建成功");
//开始侦听
listen(sock,5);
//调用线程
AfxBeginThread(&thread,0);
}
//---------------------------托盘显示---------------------------------//
m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
m_nid.hWnd = this->m_hWnd;
m_nid.uID = IDR_MAINFRAME;
m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
m_nid.uCallbackMessage = WM_SHOWTASK; // 自定义的消息名称
m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(m_nid.szTip, "服务器程序"); // 信息提示条为"服务器程序",VS2008 UNICODE编码用wcscpy_s()函数
Shell_NotifyIcon(NIM_ADD, &m_nid); // 在托盘区添加图标
// CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
// ShowWindow(SW_MINIMIZE); // 把这句话注释掉就好了
// dlg->ShowWindow(SW_HIDE); // 当最小化市,隐藏主窗口
// dlg->SetForegroundWindow();
SetTimer(1,1,NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCSocketDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCSocketDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCSocketDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCSocketDlg::OnOK()
{
// CDialog::OnOK();
}
//服务器线程
UINT thread(LPVOID p)
{
char buff[100];
CSize size;
size.cx=0;
size.cy=30;
int s=1,msgcount,loop=1,flag=0;
CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
//获得客户端数量
msgcount=dlg->getcount();
if (msgcount==-1)
loop=0;
if(loop)
{
s=1;
dlg->msgsock[msgcount]=accept(dlg->sock,(sockaddr*)&(dlg->serv),&(dlg->addlen));
if (dlg->msgsock[msgcount]==INVALID_SOCKET)
{
dlg->m_edit.SetWindowText("Error accept");
}
else
{
//启动线程
AfxBeginThread(thread,0);
dlg->SetForegroundWindow();
dlg->m_list.InsertItem(dlg->count++,"连接成功");
dlg->m_list.InsertItem(dlg->count++,inet_ntoa(dlg->serv.sin_addr));
dlg->m_list.Scroll(size);
dlg->m_button.EnableWindow(TRUE);
while(s!=SOCKET_ERROR)
{
memset(buff,0,100);
//循环接收数据
s=recv(dlg->msgsock[msgcount],buff,100,0);
if (0!=s)
{
dlg->SetForegroundWindow();
if (s!=SOCKET_ERROR)
{
TRACE( "The value of s is %d\n", s );
dlg->m_list.InsertItem(dlg->count++,buff);
dlg->m_list.Scroll(size);
dlg->sendtoall(dlg->msgsock[msgcount],buff,s);
}
}
else
break;
}
send(dlg->msgsock[msgcount],"Disconnected",100,0);
dlg->m_list.InsertItem(dlg->count++,"Disconnected");
dlg->m_list.Scroll(size);
dlg->msgsock[msgcount]=NULL;
for (int i=0;i<50;i++)
if (dlg->msgsock[i]!=NULL)
flag=1;
if (flag!=1)
dlg->m_button.EnableWindow(FALSE);
closesocket(dlg->msgsock[msgcount]);
}
}
//终止线程
AfxEndThread(0);
return 0;
}
//发送数据
void CCSocketDlg::OnButton1()
{
char buff[100];
m_edit.GetWindowText(buff,99);
m_edit.SetWindowText("");
m_list.InsertItem(count++,buff);
CSize size;
size.cx=0;
size.cy=30;
m_list.Scroll(size);
//循环向所有客户发送信息
for (int i=0;i<50;i++)
{
if (msgsock[i]!=NULL)
send(msgsock[i],buff,100,0);
}
}
CCSocketDlg::~CCSocketDlg()
{
for (int i=0;i<50;i++)
if (msgsock[i]!=NULL)
send(msgsock[i],"Disconnected",100,0);
}
//获得还没有使用的socket数组号
int CCSocketDlg::getcount()
{
for (int i=0;i<50;i++)
{
if (msgsock[i]==NULL)
return i;
}
return -1;
}
//向所有客户发送数据
void CCSocketDlg::sendtoall(SOCKET s,char *buff,int length)
{
for (int i=0;i<50;i++)
{
if (msgsock[i]!=NULL ) //&& msgsock[i]!=s
{
//发送
send(msgsock[i],buff,length,0); //
}
}
}
void CCSocketDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
ShowWindow(SW_HIDE);
KillTimer(1);
CDialog::OnTimer(nIDEvent);
}
void CCSocketDlg::OnButton2()
{
//保存
UpdateData(TRUE); //访问变量前调用
CString strip;
m_You_IP.GetWindowText(strip);
WritePrivateProfileString("SaveInfo","IP",strip,"./参数.bat");
CString strport ;
strport.Format(_T("%d"), m_port);
WritePrivateProfileString("SaveInfo","Port", strport,"./参数.bat");
MessageBox("已经保存,请重新打开软件");
exit(0);
}
// CSocketDlg.h : header file
//
#if !defined(AFX_CSOCKETDLG_H__2DFDFAF0_3473_43E6_A5CB_DBB8531B370E__INCLUDED_)
#define AFX_CSOCKETDLG_H__2DFDFAF0_3473_43E6_A5CB_DBB8531B370E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/
// CCSocketDlg dialog
class CCSocketDlg : public CDialog
{
// Construction
public:
CCSocketDlg(CWnd* pParent = NULL); // standard constructor
~CCSocketDlg();
// Dialog Data
//{{AFX_DATA(CCSocketDlg)
enum { IDD = IDD_CSOCKET_DIALOG };
CIPAddressCtrl m_You_IP;
CButton m_button;
CListCtrl m_list;
CEdit m_edit;
int m_port;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCSocketDlg)
public:
virtual BOOL DestroyWindow();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType = adjustBorder);
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CCSocketDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
afx_msg void OnButton1();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnButton2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
int GetIpAddress(const CString & sHostName,CString & sIpAddress);
int GetLocalHostName(CString &sHostName);
LRESULT OnShowTask(WPARAM wParam, LPARAM lParam);
NOTIFYICONDATA m_nid;
void SetAutoRun(BOOL bAutoRun) ;
void limited();
SOCKET sock,msgsock[50],clisock;
int addlen;
sockaddr_in serv;
int count;
int getcount();
void sendtoall(SOCKET,char*,int);
};
UINT thread(LPVOID);
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CSOCKETDLG_H__2DFDFAF0_3473_43E6_A5CB_DBB8531B370E__INCLUDED_)