1,593
社区成员
发帖
与我相关
我的任务
分享
procedure DoProc(Sender: TObject);
var
iLocalIdx, iStartIdx, iWaitNum, idx: integer;
NetwEvt: TWSANetworkEvents;
j: Cardinal;
i: Integer;
Evt: WSAEVENT;
Skt: TSocket;
tcpClt: TMyTcpClient;
ss: string;
iErr: Integer;
begin
try
if TMythread(Sender).WaitNum <= 0 then
begin
if not TMythread(Sender).IsPause then
TMythread(Sender).Suspend;
Exit;
end;
Evt := 0;
Skt := -1; //对事件对象数组进行检查网络事件(即等待某个事件的触发)
idx := WSAWaitForMultipleEvents(TMythread(Sender).WaitNum, TMythread(Sender).GetFirstEvtAddr, False, I_MaxWaitTime, False);
if (idx >= I_WaitMaxEvt) or (idx < 0)then
begin
if idx = Socket_error then
begin
Sleep(I_MaxFreeWaitTime);
//应该要调整,去掉Evt=0,或者Socket=-1的
end;
Exit;
end;
idx := idx - wsa_wait_event_0;
if TMythread(Sender).SktEvtItems[idx] = nil then Exit;
skt := TMythread(Sender).SktEvtItems[idx].SockID;
Evt := TMythread(Sender).SktEvtItems[idx].EventId;
FillChar(NetwEvt.lNetworkEvents, sizeof(NetwEvt), 0);
WSAEnumNetworkEvents(Skt, Evt, @NetwEvt);
j := NetwEvt.lNetworkEvents;
if ((j and FD_Read) > 0) or ((j and FD_OOB) > 0) then
begin
if (j and FD_Read) > 0 then
begin
iErr := NetwEvt.iErrorCode[FD_Read_BIT];
if iErr = 0 then
ProcSockEvt(sender, FD_Read, skt)
else
begin
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(skt));
if tcpClt <> nil then
begin
ss := 'Receive data error, ' + IntToStr(iErr);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seReceive, PChar(ss), iErr);
if (iErr >= 10050) and (iErr <= 10058) then
begin //严重错误要关闭Socket
if iErr <> 10056 then
ProcSockEvt(sender, FD_Close, skt);
end;
end;
end;//end of
end;
if (j and FD_OOB) > 0 then //暂时没用到
begin
iErr := NetwEvt.iErrorCode[FD_OOB_BIT];
if NetwEvt.iErrorCode[FD_OOB_BIT] = 0 then
begin
ProcSockEvt(sender, FD_OOB, skt); //OK去掉注释可用
//Exit;// 带外的不做处理
end
else
begin
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(skt));
if tcpClt <> nil then
begin
ss := 'Receive OOB data error, ' + IntToStr(iErr);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seReceive, PChar(ss), iErr);
end;
end;//end of
end;
end
else
if (j and FD_Close) > 0 then
begin
iErr := NetwEvt.iErrorCode[FD_Close_BIT];
if iErr <> 0 then
begin
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(skt));
if tcpClt <> nil then
begin
ss := 'Close Socket error, ' + IntToStr(iErr);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seClose, PChar(ss), iErr);
end;
end;//end of
ProcSockEvt(sender, FD_Close, skt);
end
else
if (j and FD_Write) > 0 then
begin
iErr := NetwEvt.iErrorCode[FD_Write_BIT];
if iErr = 0 then
ProcSockEvt(sender, FD_Write, skt)//这里没做处理,是个空的,不知道要怎么处理?
else
begin
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(skt));
if tcpClt <> nil then
begin
ss := 'Write data error, ' + IntToStr(iErr);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seSend, PChar(ss), iErr);
end;
end;//end of
end;
//一下是ProcSockEvt的FD_wrie消息,
procedure ProcSockEvt(Sender: TObject; const iOpt, iSocket: Integer);
var
AccAddr: TSockAddrIn;
err, i, j, iLen, lenAddr: Integer;
PNetwEvt: PWSANetworkEvents;
evt: wsaevent;
SktEvt: TMySktEvtItem;
tcpClt: TMyTcpClient;
ss: String;
P: Pointer;
begin
case iOpt of
Fd_read:
begin
iLen := TMyTcpBase.GetRecLength(iSocket);
if iLen <= 0 then
Exit;
P := GlobalAllocPtr(GPTR, iLen * SizeOf(Byte));
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(iSocket));
if p = nil then
begin
if tcpClt <> nil then
begin
err := GetLastError;
ss := 'Receive data error, alloc global memory failed: ' + IntToStr(err);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seReceive, PChar(ss), err);
tcpClt.Close;
end;
Exit;
end;
try
try
J := recv(iSocket, TMyArrByte(P)[0], iLen, 0);
if tcpClt = nil then Exit;
if (J <= 0) or (J <> iLen) then
begin
if tcpClt <> nil then
begin
if Assigned(tcpClt.OnErrorMsg) then
begin
err := WSAGetLastError;
//ss := '接收数据出错: ' + IntToStr(err);
ss := 'Receive data error: ' + IntToStr(err);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seReceive, PChar(ss), err);
end;
end;
Exit;
end
else
begin // J > 0 and J = iLen
if Assigned(tcpClt.OnReceiveMsg) then
begin
tcpClt.OnReceiveMsg(tcpClt, Cardinal(P), J); //OK 事件处理 ,这是线程事件
end;
end; //end of // J > 0 and J = iLen
finally
if P <> nil then
GlobalFreePtr(P);
end;
except
on E: Exception do
begin
if tcpClt <> nil then
begin
err := WSAGetLastError;
ss := 'Receive data exception.' + IntToStr(err);
if Assigned(tcpClt.OnErrorMsg) then
tcpClt.OnErrorMsg(tcpClt, seReceive, PChar(ss), err);
end;
end;
end; // end of try except
end; //FD_Read
fd_close:
begin
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(iSocket));
if tcpClt <> nil then
begin
PostMessage(tcpClt.Handle, WM_MYSOCKETMSG, iSocket, FD_CLOSE);
// end of
end;
end;
Fd_oob:
begin
iLen := 1; //MSG_oob只有一个
P := GlobalAllocPtr(GPTR, iLen * SizeOf(Byte));
try
J := recv(iSocket, TMyArrByte(P)[0], iLen, MSG_OOB);
tcpClt := TMyTcpClient(TMythread(Sender).GetTcpclientBySkt(iSocket));
if tcpClt = nil then Exit;
if (J > 0) then
begin
if Assigned(tcpClt.OnReceiveMsg) then
tcpClt.OnReceiveMsg(tcpClt, Cardinal(P), J);
end;
finally
GlobalFreePtr(P);
end;
end;//end of FD_OOB
FD_WRITE://不知道要怎么处理?
begin
end;
end;//end of case
end;