服务端
struct PER_IO_DATA
{
SOCKET sClient;
char * buff;
int nLen;
OVERLAPPED overLap;
int nIOType;
};
struct PER_HANDLE_DATA
{
SOCKET sock;
sockaddr_in addr;
};DWORD WINAPI WorkThread(LPVOID lpParameter)
{ HANDLE hComplete=lpParameter;
PER_HANDLE_DATA* pHandle=NULL;
DWORD nLen=0;
PER_IO_DATA* pIO=NULL;
while(1)
{
BOOL bOK=::GetQueuedCompletionStatus(hComplete,&nLen,
(LPDWORD)&pHandle,(LPOVERLAPPED*)&pIO->overLap,INFINITE);
if(bOK)
{
if(pIO->nIOType==IO_ACCEPT)
{
printf("accept");
}
} }
return 0;
}
void main()
{ HANDLE m_hComplete=::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
SOCKET sockListen=::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=INADDR_ANY;
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
::bind(sockListen,(sockaddr*)&addr,sizeof(sockaddr)); ::listen(sockListen,10);
// 将监听套节字关联到完成端口,注意,这里为它传递的CompletionKey为0
::CreateIoCompletionPort((HANDLE)sockListen, m_hComplete, (DWORD)0, 0); //投递5个链接请求
for(int i=0;i<5;i++)
{
PER_IO_DATA* pBuffer=(PER_IO_DATA *)::GlobalAlloc(GPTR,sizeof(PER_IO_DATA)+BUFF_SIZE);
pBuffer->buff=(char*)(pBuffer+1);
pBuffer->nIOType=IO_ACCEPT;
SOCKET sClient = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
::AcceptEx(sockListen,
pBuffer->sClient,
pBuffer->buff,
pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
&dwBytes,
&pBuffer->overLap);
} DWORD nID=0;
::CreateThread(NULL,0,WorkThread,m_hComplete,0,&nID); // 创建事件对象,不让主程序退出
HANDLE hEvent = ::CreateEvent(NULL, FALSE, FALSE, "ShutdownEvent");
::WaitForSingleObject(hEvent, INFINITE);
}
客户端:
SOCKET m_sockListen=::socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
if(INVALID_SOCKET==::connect(m_sockListen,(sockaddr*)&addr,sizeof(sockaddr)))
{
printf("error"); }
客户端connect成功后,GetQueuedCompletionStatus(),还是阻塞
struct PER_IO_DATA
{
SOCKET sClient;
char * buff;
int nLen;
OVERLAPPED overLap;
int nIOType;
};
struct PER_HANDLE_DATA
{
SOCKET sock;
sockaddr_in addr;
};DWORD WINAPI WorkThread(LPVOID lpParameter)
{ HANDLE hComplete=lpParameter;
PER_HANDLE_DATA* pHandle=NULL;
DWORD nLen=0;
PER_IO_DATA* pIO=NULL;
while(1)
{
BOOL bOK=::GetQueuedCompletionStatus(hComplete,&nLen,
(LPDWORD)&pHandle,(LPOVERLAPPED*)&pIO->overLap,INFINITE);
if(bOK)
{
if(pIO->nIOType==IO_ACCEPT)
{
printf("accept");
}
} }
return 0;
}
void main()
{ HANDLE m_hComplete=::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
SOCKET sockListen=::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=INADDR_ANY;
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
::bind(sockListen,(sockaddr*)&addr,sizeof(sockaddr)); ::listen(sockListen,10);
// 将监听套节字关联到完成端口,注意,这里为它传递的CompletionKey为0
::CreateIoCompletionPort((HANDLE)sockListen, m_hComplete, (DWORD)0, 0); //投递5个链接请求
for(int i=0;i<5;i++)
{
PER_IO_DATA* pBuffer=(PER_IO_DATA *)::GlobalAlloc(GPTR,sizeof(PER_IO_DATA)+BUFF_SIZE);
pBuffer->buff=(char*)(pBuffer+1);
pBuffer->nIOType=IO_ACCEPT;
SOCKET sClient = ::WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
::AcceptEx(sockListen,
pBuffer->sClient,
pBuffer->buff,
pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2),
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
&dwBytes,
&pBuffer->overLap);
} DWORD nID=0;
::CreateThread(NULL,0,WorkThread,m_hComplete,0,&nID); // 创建事件对象,不让主程序退出
HANDLE hEvent = ::CreateEvent(NULL, FALSE, FALSE, "ShutdownEvent");
::WaitForSingleObject(hEvent, INFINITE);
}
客户端:
SOCKET m_sockListen=::socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addr;
addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
if(INVALID_SOCKET==::connect(m_sockListen,(sockaddr*)&addr,sizeof(sockaddr)))
{
printf("error"); }
客户端connect成功后,GetQueuedCompletionStatus(),还是阻塞
解决方案 »
- 为什么我电脑上不能添加串口控件?
- 心跳包 在本机测试可以收到,拿给其他人就收不到了
- 一个连接的问题
- 得到FTP服务器上的文件的创建时间,修改时间
- Xtreme Toolkit与Xtreme Toolkit Pro有什么区别?
- 请教关于如何往CComboBoxEx 中加载位图序列的问题?急等
- 问一些基础的VC问题,请大家帮忙(不难的哦)
- 用VC到底怎么编写可共享的类库阿,我烦透了,解答者有高分相送!
- mfc是不是过时了?
- 如何把视图类中某个函数中定义和使用的动态数组的值传递到对话框类中使用?
- 使用mysql-connector-odbc提示: 驱动程序的ConfigDSN、ConfigDriver或ConfigTranslator失败
- 服务程序的问题
-------------------------------------------------
你的AcceptEx函数中的参数设置的是要求客户端连接后发送第一块数据,AcceptEx函数才会返回,这时GetQueueCompletionStatus()函数才会获取完成封包