完成端口IOCP 服务端给客户端发送数据怎么发

女神打Boss 2017-05-16 04:49:30
说下流程

多数资料都是说接收数据的。
...全文
678 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
女神打Boss 2017-05-18
  • 打赏
  • 举报
回复
参考的例子http://blog.csdn.net/piggyxp/article/details/6922277 修改几个地方_PostAccept函数中

//	FALSE == m_lpfnAcceptEx( m_pListenContext->m_Socket, pAcceptIoContext->m_sockAccept, p_wbuf->buf, p_wbuf->len - ((sizeof(SOCKADDR_IN)+16)*2),   
//		sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes, p_ol)
m_lpfnAcceptEx( m_pListenContext->m_Socket, pAcceptIoContext->m_sockAccept, p_wbuf->buf, 0,   
		sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, &dwBytes, p_ol)
_DoAccpet函数中
//	m_lpfnGetAcceptExSockAddrs(pIoContext->m_wsaBuf.buf, pIoContext->m_wsaBuf.len - ((sizeof(SOCKADDR_IN)+16)*2),  
//		sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, (LPSOCKADDR*)&LocalAddr, &localLen, (LPSOCKADDR*)&ClientAddr, &remoteLen);  

	m_lpfnGetAcceptExSockAddrs(pIoContext->m_wsaBuf.buf, 0,  
	sizeof(SOCKADDR_IN)+16, sizeof(SOCKADDR_IN)+16, (LPSOCKADDR*)&LocalAddr, &localLen, (LPSOCKADDR*)&ClientAddr, &remoteLen);
女神打Boss 2017-05-17
  • 打赏
  • 举报
回复
引用 10 楼 csdndenglu 的回复:
有QQ吗?可以加QQ说吗?
1016286846
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
UINT WorkerThread(LPVOID pParam)
{	
        P_IO_DATA temp_overlapped;    
	P_CLIENT  temp_client;   
	DWORD dTransLen;//传送的字节数
	WSABUF wsabuf;//WSASend用的
	while(1)    
	{       
		BOOL bRet = ::GetQueuedCompletionStatus(g_hIOCompletionPort, &dTransLen, (PULONG_PTR)&temp_client, (OVERLAPPED **)&temp_overlapped, WSA_INFINITE);       
		// 如果收到的是退出标志,则直接退出
		if ( EXIT_CODE == (DWORD)temp_client)
		{
			break;
		}
		//如果出现异常
		if (!bRet)
		{
			RELEASE_SOCKET(temp_client->sClient);
			//RELEASE(temp_client);
			RELEASE(temp_overlapped);
			continue;
		}

		//OutputDebugString(L"读取数据\n");
		switch (temp_overlapped->enIoType)
		{
		case SEND:
			temp_overlapped->cIoData[dTransLen] = 0;     
			ClientAddr = &temp_client->sockClientAddress;
			sprintf_s(ViewSend, "发送至%s:%d信息:%s",inet_ntoa(ClientAddr->sin_addr), ntohs(ClientAddr->sin_port), temp_overlapped->cIoData);
			break;

		case RECV:
			temp_overlapped->cIoData[dTransLen] = 0;     
			ClientAddr = &temp_client->sockClientAddress;
			memset(ViewRecv, 0, sizeof(ViewRecv));
			sprintf_s(ViewRecv, "收到%s:%d信息:%s",inet_ntoa(ClientAddr->sin_addr), ntohs(ClientAddr->sin_port), temp_overlapped->cIoData);
                       //这里添加对接收消息的处理
			MySend(temp_client->sClient, cBackData);
			break;
		}
	}   
	return 0;
}
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
有QQ吗?可以加QQ说吗?
女神打Boss 2017-05-17
  • 打赏
  • 举报
回复
引用 8 楼 csdndenglu 的回复:
MyRecv之后,读取操作被放到消息队列中,有消息到的时候,线程函数读取数据,他内部的实现咱们不用管,只需要投递了WSARecv之后在线程函数里面GetQueuedCompletionStatus()等待就行
那我收到客户端消息后想给客户端返回一个消息该怎么实现,流程是怎样的
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
MyRecv之后,读取操作被放到消息队列中,有消息到的时候,线程函数读取数据,他内部的实现咱们不用管,只需要投递了WSARecv之后在线程函数里面GetQueuedCompletionStatus()等待就行
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
引用 5 楼 CKRGD 的回复:
[quote=引用 2 楼 csdndenglu 的回复:] //发送一个异步的读操作 void MyRecv(const SOCKET & s) { P_IO_DATA p_recv = new IO_DATA; p_recv->enIoType = RECV; WSABUF wsabuf; memset(&p_recv->ol,0,sizeof(p_recv->ol)); memset(p_recv->cIoData,0,sizeof(p_recv->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); wsabuf.buf = p_recv->cIoData; wsabuf.len = 512; DWORD dwRecv; DWORD dwFlg = 0; memset(&p_recv->ol,0,sizeof(p_recv->ol) ); ::WSARecv(s, &wsabuf, 1, &dwRecv, &dwFlg, &p_recv->ol, NULL); Sleep(1); } //发送一个异步的读操作 void MySend(const SOCKET & s, char* buf) { P_IO_DATA p_send = new IO_DATA; p_send->enIoType = SEND; WSABUF wsabuf; memset(&p_send->ol,0,sizeof(p_send->ol)); memset(p_send->cIoData,0,sizeof(p_send->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); strcpy_s(p_send->cIoData, buf); wsabuf.buf = p_send->cIoData; wsabuf.len = strlen(wsabuf.buf); DWORD dwSend; DWORD dwFlg = 0; ::WSASend(s, &wsabuf, 1, &dwSend, dwFlg, &p_send->ol, NULL); }
完成端口的MyRecv读函数不应该是消息相应吗,在这个WaitForSingleObject 函数判断返回值[/quote] MyRecv之后,读取操作被放到消息队列中,有消息到的时候,线程函数读取数据
dong364 2017-05-17
  • 打赏
  • 举报
回复
在接受数据的回调函数中调用WSASend ,网上例子挺多的,可以找找,此函数是异步的,注意buffer的作用域,建议如果做跨平台的服务采用boost asio,asio组件的封装性、跨平台性和性能都是值得推荐的
女神打Boss 2017-05-17
  • 打赏
  • 举报
回复
引用 2 楼 csdndenglu 的回复:
//发送一个异步的读操作 void MyRecv(const SOCKET & s) { P_IO_DATA p_recv = new IO_DATA; p_recv->enIoType = RECV; WSABUF wsabuf; memset(&p_recv->ol,0,sizeof(p_recv->ol)); memset(p_recv->cIoData,0,sizeof(p_recv->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); wsabuf.buf = p_recv->cIoData; wsabuf.len = 512; DWORD dwRecv; DWORD dwFlg = 0; memset(&p_recv->ol,0,sizeof(p_recv->ol) ); ::WSARecv(s, &wsabuf, 1, &dwRecv, &dwFlg, &p_recv->ol, NULL); Sleep(1); } //发送一个异步的读操作 void MySend(const SOCKET & s, char* buf) { P_IO_DATA p_send = new IO_DATA; p_send->enIoType = SEND; WSABUF wsabuf; memset(&p_send->ol,0,sizeof(p_send->ol)); memset(p_send->cIoData,0,sizeof(p_send->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); strcpy_s(p_send->cIoData, buf); wsabuf.buf = p_send->cIoData; wsabuf.len = strlen(wsabuf.buf); DWORD dwSend; DWORD dwFlg = 0; ::WSASend(s, &wsabuf, 1, &dwSend, dwFlg, &p_send->ol, NULL); }
完成端口的MyRecv读函数不应该是消息相应吗,在这个WaitForSingleObject 函数判断返回值
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
读写其实是类似的,第一段代码是读操作,第二段代码是写操作,写的数据放在了参数buf里面,代码的功能实现了,还可以再优化
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
//发送一个异步的读操作
void MyRecv(const SOCKET & s) 
{    
	P_IO_DATA p_recv = new IO_DATA; 
	p_recv->enIoType = RECV;    
	WSABUF wsabuf; 
	memset(&p_recv->ol,0,sizeof(p_recv->ol));
	memset(p_recv->cIoData,0,sizeof(p_recv->cIoData));
	memset(&wsabuf, 0, sizeof(wsabuf));
	wsabuf.buf = p_recv->cIoData;
	wsabuf.len = 512;
	DWORD dwRecv;
	DWORD dwFlg = 0;
	memset(&p_recv->ol,0,sizeof(p_recv->ol) ); 
	::WSARecv(s, &wsabuf, 1, &dwRecv, &dwFlg, &p_recv->ol, NULL); 
	Sleep(1);
}

//发送一个异步的读操作
void MySend(const SOCKET & s, char* buf) 
{    
	P_IO_DATA p_send = new IO_DATA;
	p_send->enIoType = SEND;
	WSABUF wsabuf;
	memset(&p_send->ol,0,sizeof(p_send->ol));
	memset(p_send->cIoData,0,sizeof(p_send->cIoData));
	memset(&wsabuf, 0, sizeof(wsabuf));
	strcpy_s(p_send->cIoData, buf);
	wsabuf.buf = p_send->cIoData;
	wsabuf.len = strlen(wsabuf.buf);            
	DWORD dwSend;            
	DWORD dwFlg = 0;             
	::WSASend(s, &wsabuf, 1, &dwSend, dwFlg, &p_send->ol, NULL); 
}
csdndenglu 2017-05-17
  • 打赏
  • 举报
回复
//发送一个异步的读操作 void MyRecv(const SOCKET & s) { P_IO_DATA p_recv = new IO_DATA; p_recv->enIoType = RECV; WSABUF wsabuf; memset(&p_recv->ol,0,sizeof(p_recv->ol)); memset(p_recv->cIoData,0,sizeof(p_recv->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); wsabuf.buf = p_recv->cIoData; wsabuf.len = 512; DWORD dwRecv; DWORD dwFlg = 0; memset(&p_recv->ol,0,sizeof(p_recv->ol) ); ::WSARecv(s, &wsabuf, 1, &dwRecv, &dwFlg, &p_recv->ol, NULL); Sleep(1); } //发送一个异步的读操作 void MySend(const SOCKET & s, char* buf) { P_IO_DATA p_send = new IO_DATA; p_send->enIoType = SEND; WSABUF wsabuf; memset(&p_send->ol,0,sizeof(p_send->ol)); memset(p_send->cIoData,0,sizeof(p_send->cIoData)); memset(&wsabuf, 0, sizeof(wsabuf)); strcpy_s(p_send->cIoData, buf); wsabuf.buf = p_send->cIoData; wsabuf.len = strlen(wsabuf.buf); DWORD dwSend; DWORD dwFlg = 0; ::WSASend(s, &wsabuf, 1, &dwSend, dwFlg, &p_send->ol, NULL); }
赵4老师 2017-05-17
  • 打赏
  • 举报
回复
MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix, MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98 再参考: MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\SOCKSRV.DSP MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\MAKEFILE MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\SOCKSRV.C MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\SOCKSRV.H MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\SOCKCLI.H MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\SOCKCLI.C MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\COMMDEF.H MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\IOCOMPLT\README.TXT ?
女神打Boss 2017-05-16
  • 打赏
  • 举报
回复
WSASend 该怎么用

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧