//把socket绑定到完成端口 rt := BindIoCompletionCallback(AccSock,@DealAction,0); //发送异步接受请求 if FAcceptEx(FListenSock,AccSock,olData^.wsaBuffer.buf,256,256,256, @dwBytes,Poverlapped(olData)) then begin closesocket(Accsock); end;
这是我的加载winsock2 函数的方法 function LoadExFunc(sk:TSocket;fuc:TExFunc;pfun:Pointer):string; var dwBytes:DWORD; begin result := 'OK'; dwBytes := 0; if sk = INVALID_SOCKET then begin sk := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED); if sk=INVALID_SOCKET then begin result := format('加载扩展函数时创建套接字失败,错误号:%d',[WSAGetLastError]); exit; end; end; case fuc of efAcceptEx: begin if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER, @WSAID_ACCEPTEX,sizeof(WSAID_ACCEPTEX),pfun,sizeof(pfun),dwBytes,nil,nil) then begin result := format('加载扩展函数AcceptEx失败,错误号:%d',[WSAGetLastError]); exit; end; end; efDisconnectEx: begin if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER, @WSAID_DISCONNECTEX,sizeof(WSAID_DISCONNECTEX),@pfun,sizeof(pfun),dwBytes,nil,nil) then begin result := format('加载扩展函数DisconnectEx失败,错误号:%d',[WSAGetLastError]); exit; end; end; end; end;
WSAID_ACCEPTEX:TGUID = (D1: $B5367DF1; D2: $CBAC; D3: $11CF; D4: ($95, $CA, $00, $80, $5F, $48, $A1,$92));
调用wsaioctl,成功。然后,用10 socket 发送了10个AcceptEx,方法去接受新连接。并把10个socket绑定到了完成端口上(用BindIoCompletionCallback绑定的)。也成功了。可是我在客户端连接服务端,并发送数据。服务端没有任何反应。
代码:
Log('服务器正在启动...',[]);
//创建socket
FListenSock := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
if FListenSock = INVALID_SOCKET then
begin
ErrorLog('创建套接字错误:%d', [WSAGetLastError]);
exit;
end;
//设定地址和端口
ListenAddr.sin_family := AF_INET;
ListenAddr.sin_port := htons(FLocalPort);
if FLocalAddr = '' then
ListenAddr.sin_addr.S_addr := INADDR_ANY
else
ListenAddr.sin_addr.S_addr := inet_addr(pAnsichar(FLocalAddr));//一定要转化成pcahr
//绑定
if Bind(FListenSock, TSockAddr(ListenAddr),sizeof(ListenAddr)) <> 0 then
begin
ErrorLog('绑定套接字错误:%d', [WSAGetLastError]);
//closeSocket(FListenSocket);
exit;
end;
//监听
if listen(FListenSock, SOMAXCONN) <> 0 then
begin
ErrorLog('监听套接字错误:%d', [WSAGetLastError]);
//closeSocket(FListenSocket);
exit;
end; Log('创建连接池....',[]);
//初始化socket池锁和等待接受socket数量
FSockListLock := TCriticalSection.Create;
FAcceptSockCount := 0; //加载sock2 Ex方法到内存
FAcceptEx := nil;
FDisconnectEx := nil;
//LoadExFunc(FListenSock,efAcceptEx,@@FAcceptEx);
//LoadExFunc(FListenSock,efDisconnectEx,@@FDisconnectEx); FSockList := TList.Create;
//发出1000个接受socket
for i := 1 to 10 do
begin
//生成socket
AccSock := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
if AccSock = INVALID_SOCKET then
begin
ErrorLog('创建连接池错误:%d', [WSAGetLastError]);
//closeSocket(FListenSocket);
//closeAllExitsSocket
exit;
end;
//创建overlapped数据结构
new(olData);
olData^.Statu := cbaAccept;
olData^.wsaBuffer.buf := olData^.Buffer;
olData^.wsaBuffer.len := BUFFER_SIZE;
//把socket绑定到完成端口
rt := BindIoCompletionCallback(AccSock,@DealAction,0); //发送异步接受请求
if FAcceptEx(FListenSock,AccSock,olData^.wsaBuffer.buf,256,256,256,
@dwBytes,Poverlapped(olData)) then
begin
closesocket(Accsock);
end;
//维护sock列表和接受新链接的sock数量
FSockList.Add(@AccSock);
inc(FacceptSockCount);
function LoadExFunc(sk:TSocket;fuc:TExFunc;pfun:Pointer):string;
var
dwBytes:DWORD;
begin
result := 'OK';
dwBytes := 0;
if sk = INVALID_SOCKET then
begin
sk := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
if sk=INVALID_SOCKET then
begin
result := format('加载扩展函数时创建套接字失败,错误号:%d',[WSAGetLastError]);
exit;
end;
end;
case fuc of
efAcceptEx:
begin
if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER,
@WSAID_ACCEPTEX,sizeof(WSAID_ACCEPTEX),pfun,sizeof(pfun),dwBytes,nil,nil) then
begin
result := format('加载扩展函数AcceptEx失败,错误号:%d',[WSAGetLastError]);
exit;
end;
end;
efDisconnectEx:
begin
if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER,
@WSAID_DISCONNECTEX,sizeof(WSAID_DISCONNECTEX),@pfun,sizeof(pfun),dwBytes,nil,nil) then
begin
result := format('加载扩展函数DisconnectEx失败,错误号:%d',[WSAGetLastError]);
exit;
end;
end;
end;
end;