F
fxh7622
Unregistered / Unconfirmed
GUEST, unregistred user!
我现在使用完成端口进行接收数据已经可以了。
现在我想实现SERVER给客户端发送数据。我是这样做的。
将客户端和服务端连接的套接字记录在一个链表中,当需要给客户端发送数据的时候,我从这个链表中取出需要发送的套接字使用WSASEND发送出去。
其中我写的WSASEND函数实现部分没有和WSARECV函数的实现部分写在一个线程中。现在发送数据和接收数据没有问题了,可是当客户端异常端口连接的时候,我以前使用KEEPALIVE运行正常,可是现在确出现了错误,不知道是为什么?
一下是我的代码:
服务端发送数据部分:
procedure TNetControl.SendDataInfo(Socket:TSocket;SendCon:String);
var
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
begin
PerIoData := LPPER_IO_OPERATION_DATA(GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA)));
if (PerIoData = nil) then
begin
exit;
end;
ZeroMemory(@PerIoData.Overlapped, sizeof(OVERLAPPED));
PerIoData.BytesSEND := 0;
PerIoData.BytesRECV := 0;
PerIoData.DataBuf.len := Length(SendCon);
PerIoData.DataBuf.buf := Pchar(SendCon);
Flags := 0;
if (WSASend(Socket, @(PerIoData.DataBuf), 1, @SendBytes, 0,@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
Exit;
end;
end;
end;
服务端就是数据部分:
function ServerWorkerThread(CompletionPortIDointer):Integer;stdcall;
var
CompletionPort: THANDLE;
BytesTransferred: DWORD ;
PerHandleData: LPPER_HANDLE_DATA ;
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
CSite:TCSObject;
TempStr:String;
begin
CSite:=TCSObject.Create(nil);
CompletionPort:=THANDLE(CompletionPortID);
Result:= 0;
while(TRUE) do
begin
//检测完成端口的状态
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
//出现异常断线
NetControl.DelSocket(PerHandleData.Socket);
end;
.....
end;
end;
现在我想实现SERVER给客户端发送数据。我是这样做的。
将客户端和服务端连接的套接字记录在一个链表中,当需要给客户端发送数据的时候,我从这个链表中取出需要发送的套接字使用WSASEND发送出去。
其中我写的WSASEND函数实现部分没有和WSARECV函数的实现部分写在一个线程中。现在发送数据和接收数据没有问题了,可是当客户端异常端口连接的时候,我以前使用KEEPALIVE运行正常,可是现在确出现了错误,不知道是为什么?
一下是我的代码:
服务端发送数据部分:
procedure TNetControl.SendDataInfo(Socket:TSocket;SendCon:String);
var
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
begin
PerIoData := LPPER_IO_OPERATION_DATA(GlobalAlloc(GPTR, sizeof(PER_IO_OPERATION_DATA)));
if (PerIoData = nil) then
begin
exit;
end;
ZeroMemory(@PerIoData.Overlapped, sizeof(OVERLAPPED));
PerIoData.BytesSEND := 0;
PerIoData.BytesRECV := 0;
PerIoData.DataBuf.len := Length(SendCon);
PerIoData.DataBuf.buf := Pchar(SendCon);
Flags := 0;
if (WSASend(Socket, @(PerIoData.DataBuf), 1, @SendBytes, 0,@(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
begin
if (WSAGetLastError() <> ERROR_IO_PENDING) then
begin
Exit;
end;
end;
end;
服务端就是数据部分:
function ServerWorkerThread(CompletionPortIDointer):Integer;stdcall;
var
CompletionPort: THANDLE;
BytesTransferred: DWORD ;
PerHandleData: LPPER_HANDLE_DATA ;
PerIoData: LPPER_IO_OPERATION_DATA ;
SendBytes, RecvBytes: DWORD;
Flags: DWORD ;
CSite:TCSObject;
TempStr:String;
begin
CSite:=TCSObject.Create(nil);
CompletionPort:=THANDLE(CompletionPortID);
Result:= 0;
while(TRUE) do
begin
//检测完成端口的状态
if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
begin
//出现异常断线
NetControl.DelSocket(PerHandleData.Socket);
end;
.....
end;
end;