DWORD WINAPI ServerWorkerThread(LPVOID lpParam)
{
HANDLE CompletionPort = (HANDLE)lpParam;
DWORD BytesTransferred;
LPOVERLAPPED lpOverlapped;
LPPER_HANDLE_DATA PerHandleData = NULL;
LPPER_IO_DATA PerIoData = NULL;
DWORD SendBytes;
DWORD RecvBytes;
DWORD Flags;
BOOL bRet = FALSE;
while (TRUE)
{
bRet = GetQueuedCompletionStatus(CompletionPort,
&BytesTransferred,
(PULONG_PTR)
&PerHandleData,
(LPOVERLAPPED*)
&lpOverlapped,
INFINITE);
// 检查成功的返回,这儿要注意使用这个宏CONTAINING_RECORD
PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(lpOverlapped,
PER_IO_DATA,
Overlapped);
// 先检查一下,看看是否在套接字上已有错误发生
if (0 == BytesTransferred)
{
closesocket(PerHandleData->Socket);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
continue;
}
// 数据处理
// 成功了!!!这儿就收到了来自客户端的数据
// cout << PerIoData->DataBuf.buf << endl;
// MessageBox("sffdasf");
AfxMessageBox(PerIoData->DataBuf.buf);
Flags = 0;
// 为下一个重叠调用建立单I/O操作数据
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
PerIoData->DataBuf.len = 1024;
PerIoData->DataBuf.buf = PerIoData->buffer;
PerIoData->OperationType = 0; // read
WSARecv(PerHandleData->Socket,
&(PerIoData->DataBuf),
1,
&RecvBytes,
&Flags,
&(PerIoData->Overlapped),
NULL);
}
return 0;
}
int StartWinsock(void)
{
WSADATA wsa;
return WSAStartup(MAKEWORD(2,2),&wsa); //2,0
}
void Ccptest_netDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
SYSTEM_INFO SystemInfo;
CString ctemp;
struct sockaddr_in InternetAddr; /* 目标地址 */
SOCKET Listen;
int i;
WSADATA wsd;
HANDLE CompletionPort;
// Load Winsock
StartWinsock();//MAKEWORD(2,2), &wsd);
// Step 1:
// Create an I/O completion port
CompletionPort = CreateIoCompletionPort(
INVALID_HANDLE_VALUE, NULL, 0, 0);
// Step 2:
// Determine how many processors are on the system
GetSystemInfo(&SystemInfo);
// Step 3:
// Create worker threads based on the number of
// processors available on the system. For this
// simple case, we create one worker thread for each
// processor.
for(i = 0; i < SystemInfo.dwNumberOfProcessors; i++)
{
HANDLE ThreadHandle;
// Create a server worker thread, and pass the
// completion port to the thread. NOTE: the
// ServerWorkerThread procedure is not defined
// in this listing.
ThreadHandle = CreateThread(NULL, 0,
ServerWorkerThread, CompletionPort,
0, NULL);
// Close the thread handle
CloseHandle(ThreadHandle);
}
// Step 4:
// Create a listening socket
Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
WSA_FLAG_OVERLAPPED);
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(5150);
bind(Listen, (PSOCKADDR) &InternetAddr,
sizeof(InternetAddr));
// Prepare socket for listening
listen(Listen, 5);
while(TRUE)
{
PER_HANDLE_DATA *PerHandleData=NULL;
SOCKADDR_IN saRemote;
SOCKET Accept;
int RemoteLen;
// Step 5:
// Accept connections and assign to the completion
// port
RemoteLen = sizeof(saRemote);
Accept = WSAAccept(Listen, (SOCKADDR *)&saRemote, &RemoteLen,NULL, 0);
// Step 6:
// Create per-handle data information structure to
// associate with the socket
PerHandleData = (LPPER_HANDLE_DATA)
GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));
printf("Socket number %d connected/n", Accept);
PerHandleData->Socket = Accept;
memcpy(&PerHandleData->ClientAddr, &saRemote, RemoteLen);
// Step 7:
// Associate the accepted socket with the
// completion port
CreateIoCompletionPort((HANDLE) Accept,
CompletionPort, (DWORD) PerHandleData, 0);
// Step 8:
// Start processing I/O on the accepted socket.
// Post one or more WSASend() or WSARecv() calls
// on the socket using overlapped I/O.
WSASend(Listen,
}
}
Top
可以 但有必要吗Top
upTop
网上有很多完成断口的例子
http://www.vckbase.com/document/viewdoc/?id=980Top
为什么说没必要??????Top
只是一书之言,微软建议服务端用完成端口,客户端使用基于消息的socket通讯!Top
对于需要连接大量客户端的服务器来说, 完成端口是不错的选择。
对于客户端来说,没有必要。Top
可以的,但完成端口不能在win98上使用.客户端都是win2k以上吗?Top
没有必要Top
应该是可以的。
只需要把你的套接字与完成端口关联起来,然后投递异步的请求,在线程池里面处理完成的i/o请求就可以了。
www.codeproject.com里面有一个完成端口的例子,写的还可以,不过有很多bug,下载了学习一下。Top
客户端要处理很多连接吗?
那你不成了服务器了呀?Top
一个客户机就那么多的连接, 那服务器器不是受不了了吗?
是不是想把它给弄死呀Top
完全可以的,你试试吧!!!Top
偶就是想同时边上万儿八千的服务器,采网页。。。。。。。。。。
但好像关于完成端口主动连接的例程特别少!!!Top
偶就是想同时连上万儿八千的服务器,采网页。。。。。。。。。。
但好像关于完成端口主动连接的例程特别少!!!
Top
望高人们给点例程Top
完成端口主动连接的一个典型例子就是"代理服务器". 你可以找一下完成端口模型的代理服务器的代码,里面既有响应连接,也有主动连接. 但是如果只是做一个纯CLIENT,建议没有必要用IOCP这么复杂,完全可以用重叠IO模型或者SELECT模型.IOCP的优势是体现在大量并发连接的响应与管理上,所以来做服务器更加可以体现其优势出来.Top
服務器的級聯還是用得上的
1:先建立個連接
2:Connect到對方得服務器
3:將socket句柄綁定在iocp句柄上
4:投遞一個WSARecv操作Top
SmallBigCat(。。。) 说的对,的确是那样的Top
偶就是要同时连上万儿八千个服务器。Top
没关系,无论是服务器还是客户端,用TCP或UDP都可以,
其实IOCP只是一种实现IO输入输出模型,对它来说,根本不知道
是socket句柄或其它句柄,实际上这个模型是一个被动模型,
IO句柄是否可以关联到IOCP,其实是看这个IO句柄是否支持它有关。
Top
connect成功以后,
CreateIoCompletionPort((HANDLE) client,
CompletionPort, (DWORD) PerHandleData, 0);
将连接成功的socket加到完成端口,以后对于这个socket调用的WSASend,WSARecv都会在这个完成端口上得到通知.
具体的代码自己写一下吧.
我们公司模拟大量客户端测试的代码就用了用于连接的完成端口.
效果还不错.