当前位置:首页 > 芯闻号 > 充电吧
[导读]与上一个帖子对应,可以互相通讯。头文件:// TCPCustom_CE.h: interface for the CTCPCustom_CE class. // ///////////////////

与上一个帖子对应,可以互相通讯。

头文件:

// TCPCustom_CE.h: interface for the CTCPCustom_CE class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_TCPCUSTOM_CE_H__0E8B4A18_8A99_438E_B5F6_B5985FFC117D__INCLUDED_)
#define AFX_TCPCUSTOM_CE_H__0E8B4A18_8A99_438E_B5F6_B5985FFC117D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include#include "TCPServer_CE.h"

class CTCPCustom_CE  
{
public:
	CTCPCustom_CE();
	virtual ~CTCPCustom_CE();
public:
	CTCPServer_CE * m_pTCPServer_CE; //引用TCP服务端监听Socket

	CString m_RemoteHost; //远程主机IP地址
	DWORD m_RemotePort; //远程主机端口号
	SOCKET m_socket;      //通讯Socket句柄
private:
	HANDLE m_exitThreadEvent;  //通讯线程退出事件句柄
	HANDLE m_tcpThreadHandle;  //通讯线程句柄
private:
    //通讯线程函数
	static DWORD SocketThreadFunc(PVOID lparam);
public:
	//打开socket,创建通讯线程
	bool Open(CTCPServer_CE *pTCPServer);
    
	//关闭socket,关闭线程,释放Socket资源
	bool Close();

	//向客户端发送数据
	bool  SendData(const char * buf , int len);

};

#endif // !defined(AFX_TCPCUSTOM_CE_H__0E8B4A18_8A99_438E_B5F6_B5985FFC117D__INCLUDED_)


源文件:

// TCPCustom_CE.cpp: implementation of the CTCPCustom_CE class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TCPServer.h"
#include "TCPCustom_CE.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//构造函数
CTCPCustom_CE::CTCPCustom_CE()
{
   //创建线程退出事件
   m_exitThreadEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
}

//析构函数
CTCPCustom_CE::~CTCPCustom_CE()
{
   //关闭线程退出事件
   CloseHandle(m_exitThreadEvent);
}

/*--------------------------------------------------------------------
【函数介绍】:  此线程用于监听与客户端连接的socket通讯的事件,例如当接收到数据、
			   连接断开和通讯过程发生错误等事件
【入口参数】:  lparam:无类型指针,可以通过此参数,向线程中传入需要用到的资源。
			   在这里我们将CTCPCustom_CE类实例指针传进来
【出口参数】:  (无)
【返回  值】:  返回值没有特别的意义,在此我们将返回值设为0。
---------------------------------------------------------------------*/
DWORD CTCPCustom_CE::SocketThreadFunc(PVOID lparam)
{
	CTCPCustom_CE *pSocket;
	//得到CTCPCustom类实例指针
	pSocket = (CTCPCustom_CE*)lparam;
	//定义读事件集合
	fd_set fdRead;  
	int ret;
	TIMEVAL	aTime;
	aTime.tv_sec = 1;
	aTime.tv_usec = 0;
	while (TRUE)
	{
        //收到退出事件,结束线程
		if (WaitForSingleObject(pSocket->m_exitThreadEvent,0) == WAIT_OBJECT_0)
		{
			break;
		}
		//置空读事件集合
		FD_ZERO(&fdRead);
		//给pSocket设置读事件
		FD_SET(pSocket->m_socket,&fdRead);
		//调用select函数,判断是否有读事件发生
		ret = select(0,&fdRead,NULL,NULL,&aTime);
		
		if (ret == SOCKET_ERROR)
		{
			//触发错误事件
			pSocket->m_pTCPServer_CE->OnClientError(pSocket->m_pTCPServer_CE->m_pOwnerWnd,pSocket,1);
			//关闭socket
			closesocket(pSocket->m_socket);
			break;
		}
		
		if (ret > 0)
		{
			//判断是否读事件
			if (FD_ISSET(pSocket->m_socket,&fdRead))
			{
				char recvBuf[1024];
				int recvLen;
				ZeroMemory(recvBuf,1024);
				recvLen = recv(pSocket->m_socket,recvBuf, 1024,0); 
				if (recvLen == SOCKET_ERROR)
				{
					int nErrorCode = WSAGetLastError();
					//触发与客户端端连接的Socket错误
					pSocket->m_pTCPServer_CE->OnClientError(pSocket->m_pTCPServer_CE->m_pOwnerWnd,pSocket,nErrorCode);
					//触发与客户端端连接的Socket关闭事件
					pSocket->m_pTCPServer_CE->OnClientClose(pSocket->m_pTCPServer_CE->m_pOwnerWnd,pSocket);
					//关闭socket
					closesocket(pSocket->m_socket);
					break;

				}
				//表示连接已经从容关闭
				else if (recvLen == 0)
				{
					pSocket->m_pTCPServer_CE->OnClientClose(pSocket->m_pTCPServer_CE->m_pOwnerWnd,pSocket);
					//关闭socket
					closesocket(pSocket->m_socket);
					break;
				}
				else
				{
				   //触发与客户端端连接的Socket读事件
                   pSocket->m_pTCPServer_CE->OnClientRead(pSocket->m_pTCPServer_CE->m_pOwnerWnd,pSocket,recvBuf,recvLen);
				}
			}
		}
	}
	return 0;
}

/*--------------------------------------------------------------------
【函数介绍】: 打开socket,创建通讯线程
【入口参数】:  pTCPServer指向服务器端监听socket
【出口参数】:  (无)
【返回  值】:  TRUE:打开成功;FALSE:打开失败
---------------------------------------------------------------------*/
bool CTCPCustom_CE::Open(CTCPServer_CE *pTCPServer)
{
   //创建通讯线程
   m_tcpThreadHandle = CreateThread(NULL,0,SocketThreadFunc,this,0,NULL);
   if (m_tcpThreadHandle == NULL)
   {
	   closesocket(m_socket);
	   return FALSE;
   }
   //设置通讯模式为异步模式
   DWORD ul= 1;
   ioctlsocket(m_socket,FIONBIO,&ul);
   m_pTCPServer_CE = pTCPServer;
   return TRUE;
}

/*--------------------------------------------------------------------
【函数介绍】: 关闭socket,关闭线程,释放Socket资源
【入口参数】:  (无)
【出口参数】:  (无)
【返回  值】:  TRUE:成功关闭;FALSE:关闭失败
---------------------------------------------------------------------*/
bool CTCPCustom_CE::Close()
{
   //发送通讯线程结束事件
   SetEvent(m_exitThreadEvent);
   Sleep(1000);
   //关闭Socket,释放资源
   int err = closesocket(m_socket);
   if (err == SOCKET_ERROR)
   {
	   return FALSE;
   }
   return TRUE;
}


/*-----------------------------------------------------------------
【函数介绍】: 向客户端发送数据
【入口参数】: buf:待发送的数据
              len:待发送的数据长度
【出口参数】: (无)
【返回  值】: TRUE:发送数据成功;FALSE:发送数据失败
------------------------------------------------------------------*/
bool CTCPCustom_CE::SendData(const char * buf , int len)
{
	int nBytes = 0;
	int nSendBytes=0;
			
	while (nSendBytes < len)
	{
	    nBytes = send(m_socket,buf+nSendBytes,len-nSendBytes,0);
		if (nBytes==SOCKET_ERROR )
		{
			int iErrorCode = WSAGetLastError();
			//触发socket的Error事件
			m_pTCPServer_CE->OnClientError(m_pTCPServer_CE->m_pOwnerWnd,this,iErrorCode);
			//触发与服务器端断开连接事件
			m_pTCPServer_CE->OnClientClose(m_pTCPServer_CE->m_pOwnerWnd,this);
			//关闭socket
			Close();
			return FALSE;
		}

		nSendBytes = nSendBytes + nBytes;
		
		if (nSendBytes < len)
		{
		    Sleep(1000);
		}
	} 
	return TRUE; 
}



调用示例:

BOOL CTCPServerDlg::OnInitDialog()
{
	//m_bFullScreen = FALSE;
	CDialog::OnInitDialog();

	// 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
	
	CenterWindow(GetDesktopWindow());	// center to the hpc screen

	// TODO: Add extra initialization here
	// 设置默认值
	m_localPort = 5000;
	UpdateData(FALSE);
	return TRUE;  // return TRUE  unless you set the focus to a control
}


// 客户端连接建立事件处理函数
void CALLBACK  CTCPServerDlg::OnClientConnect(CWnd* pWnd,CTCPCustom_CE* pTcpCustom)
{
	CTCPServerDlg * pDlg = (CTCPServerDlg*)pWnd;
	CListBox * pLstConn = (CListBox*)pDlg->GetDlgItem(IDC_LSTCONN);
	ASSERT(pLstConn != NULL);
	pLstConn->AddString(pTcpCustom->m_RemoteHost + _T("建立连接"));
	
	RETAILMSG(1,(TEXT("==OnClientConnect=%s rn"),pTcpCustom->m_RemoteHost));

	gTcpSendObj = *pTcpCustom;
}

// 客户端SOCKET关闭事件处理函数
void  CALLBACK CTCPServerDlg::OnClientClose(CWnd* pWnd,CTCPCustom_CE* pTcpCustom)
{
	CTCPServerDlg * pDlg = (CTCPServerDlg*)pWnd;
	int iIndex = 0;
	
	CListBox * pLstConn = (CListBox*)pDlg->GetDlgItem(IDC_LSTCONN);
	ASSERT(pLstConn != NULL);
	iIndex = pLstConn->FindString(iIndex,pTcpCustom->m_RemoteHost + _T("建立连接"));
	if (iIndex == LB_ERR)
	{
		return;
	}
	pLstConn->DeleteString(iIndex); 
	
	RETAILMSG(1,(TEXT("==OnClientClose=%s rn"),pTcpCustom->m_RemoteHost));
}

// 服务器端收到来自客户端的数据
void CALLBACK CTCPServerDlg::OnClientRead(CWnd* pWnd,CTCPCustom_CE* pTcpCustom,const char *buf,int len)
{
    CString strRecv;
	CString strLen;
	strLen.Format(L"%d",len);
	strRecv = buf;
	CTCPServerDlg * pDlg = (CTCPServerDlg*)pWnd;
	CListBox * pLstRecv = (CListBox*)pDlg->GetDlgItem(IDC_LSTRECV);
	ASSERT(pLstRecv != NULL);
	
	pLstRecv->AddString(_T("************************************"));
	pLstRecv->AddString(_T("来自: ") + pTcpCustom->m_RemoteHost);
	pLstRecv->AddString(_T("数据长度:")+strLen);
	pLstRecv->AddString(strRecv);
	
	RETAILMSG(1,(TEXT("===%s rn"),pTcpCustom->m_RemoteHost));
	if (!pTcpCustom->SendData("OK",strlen("OK")))
	{
		AfxMessageBox(_T("发送失败"));
	}
}

//客户端Socket错误事件处理函数
void CALLBACK CTCPServerDlg::OnClientError(CWnd* pWnd,CTCPCustom_CE* pTcpCustom,int nErrorCode)
{
	
	RETAILMSG(1,(TEXT("==OnClientError=%s rn"),pTcpCustom->m_RemoteHost));
}

//服务器端Socket错误事件处理函数
void CALLBACK CTCPServerDlg::OnServerError(CWnd* pWnd,CTCPServer_CE* pTcpServer_CE,int nErrorCode)
{
}

// 监听按钮单击事件方法
void CTCPServerDlg::OnBtnlisten() 
{
	UpdateData(TRUE);
	// 设置 m_tcpServer 属性
   	m_tcpServer.m_LocalPort = m_localPort;
	m_tcpServer.m_pOwnerWnd = this;
	m_tcpServer.OnClientConnect = OnClientConnect;
	m_tcpServer.OnClientClose = OnClientClose;
	m_tcpServer.OnClientRead = OnClientRead;
	m_tcpServer.OnClientError = OnClientError;
	m_tcpServer.OnServerError = OnServerError;
	if (m_tcpServer.Open() EnableWindow(FALSE);
	
	CButton * pBtnClose = (CButton*)GetDlgItem(IDC_BTNCLOSE);
	ASSERT(pBtnClose != NULL);
	pBtnClose->EnableWindow(TRUE);	
	
	CButton *pBtnSend = (CButton*)GetDlgItem(IDC_SendBtn);
	ASSERT(pBtnSend != NULL);
	pBtnSend->EnableWindow(TRUE);
}

//关闭按钮单击事件代码 
void CTCPServerDlg::OnBtnclose() 
{
	if (m_tcpServer.Close() EnableWindow(TRUE);

	CButton * pBtnClose = (CButton*)GetDlgItem(IDC_BTNCLOSE);
	ASSERT(pBtnClose != NULL);
	pBtnClose->EnableWindow(FALSE);		
	
	CButton *pBtnSend = (CButton*)GetDlgItem(IDC_SendBtn);
	ASSERT(pBtnSend != NULL);
	pBtnSend->EnableWindow(FALSE);

	CListBox * pLstConn = (CListBox*)GetDlgItem(IDC_LSTCONN);
	ASSERT(pLstConn != NULL);
	
	CListBox * pLstRecv = (CListBox*)GetDlgItem(IDC_LSTRECV);
	ASSERT(pLstRecv != NULL);
	
	pLstConn->ResetContent();
	pLstRecv->ResetContent();
	
}

void CTCPServerDlg::OnSendBtn() 
{
	// TODO: Add your control notification handler code here
	
	if (!gTcpSendObj.SendData("Send data ok(Server)",strlen("Send data ok(Server)")))
	{
		AfxMessageBox(_T("发送失败"));
	}
}




本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭