基于 VS2015 VC++ 网络编程socket 服务器端

github源代码地址: https://github.com/duijiudanggecl/VC-.git
ServerSocket.cpp
此类继承于 CSocket

CServerSocket::CServerSocket()
{
}

CServerSocket::~CServerSocket()
{
}

void CServerSocket::OnReceive(int nErrorCode)

{

m_pDlg->RecvData(this);                           // 接收数据

CSocket::OnReceive(nErrorCode);

}

void CServerSocket::OnClose(int nErrorCode)

{

m_pDlg -> RemoveClient(this);                   // 删除下线用户

CSocket::OnClose(nErrorCode);

}

void CServerSocket::OnAccept(int nErrorCode)

{

m_pDlg->AddClient();                                  //添加上线用户

CSocket::OnAccept(nErrorCode);

}

主对话框:

CServerDlg::CServerDlg(CWnd* pParent / =NULL/)
CDialogEx(IDD_SERVER_DIALOG, pParent)
, m_port(0)
, m_usercount(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);

DDX_Control(pDX, IDC_PORT, port);
DDX_Control(pDX, IDC_EventRecord, m_event);
DDX_Control(pDX, IDC_USERCOUNT, usercount);

}

BEGIN_MESSAGE_MAP(CServerDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_StateServer, &CServerDlg::OnBnClickedStateserver)
ON_BN_CLICKED(IDC_SEND, &CServerDlg::OnBnClickedSend)
END_MESSAGE_MAP()

// CServerDlg 消息处理程序

BOOL CServerDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();

// 将“关于...”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
	BOOL bNameValid;
	CString strAboutMenu;
	bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
	ASSERT(bNameValid);
	if (!strAboutMenu.IsEmpty())
	{
		pSysMenu->AppendMenu(MF_SEPARATOR);
		pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}

// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE);			// 设置大图标
SetIcon(m_hIcon, FALSE);		// 设置小图标

// TODO: 在此添加额外的初始化代码

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

void CServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。

void CServerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

	SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

	// 使图标在工作区矩形中居中
	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;

	// 绘制图标
	dc.DrawIcon(x, y, m_hIcon);
}
else
{
	CDialogEx::OnPaint();
}

}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CServerDlg::OnQueryDragIcon()
{
return static_cast(m_hIcon);
}

void CServerDlg::OnBnClickedStateserver()
{
// TODO: 在此添加控件通知处理程序代码

//SetDlgItemInt(IDC_PORT, m_port);
//SetDlgItemInt(IDC_USERCOUNT, m_usercount);

CString strText(_T(""));
GetDlgItemText(IDC_PORT, strText);
//double val1 = _tcstod(strText, NULL); // 浮点数用这个   
short m_port = _ttoi(strText); // 整数用这个




if (m_connect)

{

	delete listenSocket;

	listenSocket = NULL;

	m_connect = false;

	SetDlgItemText(IDC_StateServer, _T("打开服务器"));

	UpdateEvent(_T("系统关闭服务器."));

	return;

}

listenSocket = new CServerSocket();

listenSocket->m_pDlg = this;

// 指定对话框为主对话框,不能少了这句

UpdateData(true);

if (!listenSocket->Create(m_port)) //8000

	// 创建服务器的套接字,IP地址默认本机IP

{

	AfxMessageBox(_T("创建套接字错误!"));

	listenSocket->Close();

	return;

}

if (!listenSocket->Listen())

{

	AfxMessageBox(_T("监听失败!"));

	listenSocket->Close();

	return;

}

m_connect = true;

SetDlgItemText(IDC_StateServer, _T("关闭服务器"));

UpdateEvent(_T("系统打开服务器."));

}

void CServerDlg::AddClient()

{

CServerSocket *pSocket = new CServerSocket;

pSocket->m_pDlg = this;

listenSocket->Accept(*pSocket);

pSocket->AsyncSelect(FD_READ | FD_WRITE | FD_CLOSE);

m_clientList.AddTail(pSocket);   //将所有客户连接加入到链表中 

m_usercount = m_clientList.GetCount();

char ary[100] = "";
_itoa_s(m_usercount, ary, 10);//十进制-22


CString  str;
 //str = T2A(ary);

 str= CString(ary);

SetDlgItemText(IDC_USERCOUNT, str);

UpdateData(false);

UpdateEvent(_T("用户连接服务器."));

SendMSG(_T("Chen"));

}

void CServerDlg::RemoveClient(CServerSocket* pSocket)

{

POSITION nPos = m_clientList.GetHeadPosition();

POSITION nTmpPos = nPos;

while (nPos)

{

	CServerSocket* pSockItem = (CServerSocket*)m_clientList.GetNext(nPos);

	if (pSockItem->m_hSocket == pSocket->m_hSocket)

	{

		pSockItem->Close();

		delete pSockItem;

		m_clientList.RemoveAt(nTmpPos);

		m_usercount = m_clientList.GetCount();



		char ary[100] = "";
		_itoa_s(m_usercount, ary, 10);//十进制-22


		CString  str;
		//str = T2A(ary);

		str = CString(ary);

		SetDlgItemText(IDC_USERCOUNT, str);



		UpdateData(false);

		UpdateEvent(_T("用户离开."));

		return;

	}

	nTmpPos = nPos;

}

}

#define OUTINFO_0_PARAM(fmt) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s",“INFO–”,fmt);sprintf_s(sOut,(sfmt));OutputDebugStringA(sOut);}
#define OUTINFO_1_PARAM(fmt, var) { CHAR sOut[256]; CHAR sfmt[50]; sprintf_s(sfmt, “%s%s”, “INFO–”, fmt); sprintf_s(sOut, (sfmt), var); OutputDebugStringA(sOut); }
#define OUTINFO_2_PARAM(fmt, var1, var2) { CHAR sOut[256]; CHAR sfmt[50]; sprintf_s(sfmt, “%s%s”, “INFO–”, fmt); sprintf_s(sOut, (sfmt), var1, var2); OutputDebugStringA(sOut); }
#define OUTINFO_3_PARAM(fmt, var1, var2, var3) { CHAR sOut[256]; CHAR sfmt[50]; sprintf_s(sfmt, “%s%s”, “INFO–”, fmt); sprintf_s(sOut, (sfmt), var1, var2, var3); OutputDebugStringA(sOut); }

void CServerDlg::RecvData(CServerSocket* pSocket)

{

char* pData = NULL;

pData = new char[1024];

memset(pData, 0, sizeof(char) * 1024);

UCHAR leng = 0;

CString str;

if (pSocket->Receive(pData, 1024, 0) != SOCKET_ERROR)

{

	str = pData;


	//USES_CONVERSION;
	//调用函数,T2A和W2A均支持ATL和MFC中的字符转换
	//char * pFileName = T2A(str);
	//OUTINFO_1_PARAM("---%s-----\n", pFileName);


	UpdateEvent(str);

	//ControlPC(str);     // 依据指令控制电脑

	//SendMSG(str);     // 转发数据给所有用户,包括发送数据的用户

}

delete pData;

pData = NULL;

}

void CServerDlg::UpdateEvent(CString str)

{

CString string;

CTime time = CTime::GetCurrentTime();

// 获取系统当前时间

str += _T("\r\n");

// 用于换行显示日志

string = time.Format(_T("%Y/%m/%d %H:%M:%S  ")) + str;

// 格式化当前时间

int lastLine = m_event.LineIndex(m_event.GetLineCount() - 1);

//获取编辑框最后一行索引

m_event.SetSel(lastLine + 1, lastLine + 2, 0);

//选择编辑框最后一行

m_event.ReplaceSel(string);                                                             //替换所选那一行的内容

}

BOOL CServerDlg::WChar2MByte(LPCWSTR srcBuff, LPSTR destBuff, int nlen)

{

int n = 0;

n = WideCharToMultiByte(CP_OEMCP, 0, srcBuff, -1, destBuff, 0, 0, FALSE);

if (n<nlen)return FALSE;

WideCharToMultiByte(CP_OEMCP, 0, srcBuff, -1, destBuff, nlen, 0, FALSE);

return TRUE;

}

void CServerDlg::SendMSG(CString str)

{

char *pSend = new char[str.GetLength()];

memset(pSend, 0, str.GetLength() * sizeof(char));

if (!WChar2MByte(str.GetBuffer(0), pSend, str.GetLength()))

{

	AfxMessageBox(_T("字符转换失败"));

	delete pSend;

	return;

}

POSITION nPos = m_clientList.GetHeadPosition();

while (nPos)

{

	CServerSocket* pTemp = (CServerSocket*)m_clientList.GetNext(nPos);

	pTemp->Send(pSend, str.GetLength());

}

delete pSend;

}

void CServerDlg::ControlPC(CString AndroidControl)

{

if (AndroidControl == "mop")             //打开播放器

{

	ShellExecute(NULL, _T("open"), _T("C:\\Program Files (x86)\\KuGou\\KGMusic\\KuGou.exe"), NULL, NULL, SW_SHOWNORMAL);

}

else if (AndroidControl == "mcl")         //关闭播放器

{

	DWORD id_num;

	HWND hWnd = ::FindWindow(_T("kugou_ui"), NULL);

	GetWindowThreadProcessId(hWnd, &id_num);

	//注意:第二个参数是进程的ID,返回值是线程的ID。

	HANDLE hd = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id_num);

	TerminateProcess(hd, 0);

}

else if (AndroidControl == "mpl" || AndroidControl == "mpa")                //播放/暂停

{

	keybd_event(VK_LMENU, 0, 0, 0);

	keybd_event(VK_F5, 0, 0, 0);

	keybd_event(VK_F5, 0, KEYEVENTF_KEYUP, 0);

	keybd_event(VK_LMENU, 0, KEYEVENTF_KEYUP, 0);

}

}

BOOL CServerDlg::PreTranslateMessage(MSG* pMsg)

{

switch (pMsg->wParam)

{

case VK_RETURN:

case VK_ESCAPE:

	return true; break;

}

return CDialogEx::PreTranslateMessage(pMsg);

}

void CServerDlg::OnBnClickedSend()
{
// TODO: 在此添加控件通知处理程序代码

CString str;

GetDlgItemText(IDC_EDIT_SEND, str);





//USES_CONVERSION;
//调用函数,T2A和W2A均支持ATL和MFC中的字符转换
//char * Tempstr = T2A(str);

//strcpy(pBuff, str.GetBuffer(0));




CServerDlg::SendMSG( str);

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
光 盘 说 明 为了方便读者学习,本书附带了一张光盘,下面对光盘内容及使用方法进行简要的介绍。 1.光盘的运行环境 硬件环境:CPU的主频在200MHz以上、内存在64MB以上。 软件平台:操作系统为Windows 98/Me/NT/2000/XP(推荐使用Windows 2000/XP),调试环境为Visual C++ 6.0及其以上版本(如果不做说明,则默认为Visual C++ 6.0)。 2.光盘的使用方法及注意事项 将本书的源代码拷入硬盘中,用Visual C++打开项目文件,即可编译运行。 3.光盘的主要内容 光盘中存放的是书中涉及的所有实例的源代码和经过编译后的应用程序。所有程序均经过测试,仅供读者学习时使用,不能用作其他商业用途。如果使用时遇到任何问题,请发Email至Fourwei@zj.com,我们将提供全面的解答。 4.光盘目录 (1)基本网络编程实例 Winsock实现网络聊天室【\chap1\ChatRoom(Winsock)】 CSocket实现聊天室【\chap1\ChatRoom(Csocket)】 (2)本地计算机网络编程实例 获取计算机的名称和IP地址【\chap2\Local】 获取计算机的子网掩码【\chap2\ Local】 获取计算机的DNS设置【\chap2\ Local】 获取计算机的网卡地址【\chap2\ Local】 获取计算机安装的协议【\chap2\ Local】 获取计算机提供的服务【\chap2\ Local】 获取计算机的所有网络资源【\chap2\ Local】 修改本地计算机的所有网络设置【\chap2\ Local】 获取计算机TCP/IP协议的所有信息【\chap2\ Local】 (3)局域网网络通信编程实例 获取网上邻居【\chap3\Neighbor】 lIP地址和计算机名之间的转换【\chap3\Neighbor】 l映射网络驱动器【\chap3\Neighbor】 l消息发送程序Net Send【\chap3\Neighbor】 l获取局域网内其他计算机的信息【\chap3\ NeighborInfo】 (4)IE编程实例 简单的浏览器的实现【\chap4\MyBrowser】 删除IE相关历史记录【\chap4\DelHistory】 将应用程序加入到IE工具栏【\chap4\AddToToolBar】 超级链接的实现【\chap4\HyperLink】 禁止IE的弹出窗口【\chap4\StopPopup】 禁止浏览某些网站【\chap4\StopTravel】 IE收藏夹【\chap4\ MyBrowser】 创建桌面快捷方式和活动桌面【\chap4\ShortCut】 (5)基本网络编程实例 点对点文件传输【\chap5\Transfer】 大型文件传输【\chap5\Transfer】 端口扫描程序【\chap5\ MyPortScanner】 Finger编程【\chap5\MyFinger】 Sniff编程【\chap5\MySniff】 Internet文件下载【\chap5\ InternetDownload】 (6)网络通信协议编程 FTP协议【\chap6\FTP】 Email协议【\chap6\Email】 ICMP协议【\chap6\ICMP】 RAS协议【\chap6\RAS】 TAPI协议【\chap6\TAPI】 Telnet协议【\chap6\Telnet】 HTTP协议 【\chap6\HTTP】 (7)Modem /串口通信编程 Modem编程【\chap7\Modem】 MSCOMM控件编程【\chap7\MSCOMM】 串口通信API编程【\chap7\MySerialCom】 (8)代理服务器编程实例 Socks 5协议编程【\chap8\Socks5】 HTTP代理服务器【\chap8\HTTP代理服务】 (9)高级网络通信编程实例 串口通信编程实例【\chap9\SerialPort】 网络流量监控【\chap9\NetTraffic】 网站下载【\chap9\ Snag】 网络五子棋系统【\chap9\FiveChess】 语音聊天【\chap9\ ChatRoom】 远程监控【\chap9\RemoteControl】 赠送实例 类似网络蚂蚁的断点续传程序【\Appendix\NetAnts】 网络多播程序【\Appendix\BroadCast】 界面美观的文字聊天程序【\Appendix\Chat】 语音电话【\Appendix\PhoneCall】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值