-
Пример использования.
Sock.Host:='127.0.0.1'; Sock.Port:=8080; If Not Sock.Connect Then Begin ShowMessage(IntToStr(Sock.Error)); Exit; End; While (not Terminated)and(Not Sock.Disconnected) do Begin Sock.GetStatus; If Sock.ErrorPresent Then {obrabativaem oshibku} If Sock.CanRead Then Size:=Sock.ReceiveLength; //Potom chitaem -> Sock.Read If Sock.CanWrite Then //Pichem End; Sock.Close;
-
Сам модуль.
unit NewSock;
interface Uses WinSock;
CONST SOCKET_ERROR=WINSOCK.SOCKET_ERROR; Type TNewSock=Class Private FSock :Integer; FClose :Boolean; FError :Integer; FCanRead :Boolean; FCanWrite:Boolean; FOnError :Boolean; FAddr :TSockAddr; FHost :String; FPort :Word; Public Procedure Close; Procedure GetStatus(Const TimeOut:Integer=50); Function GetRemoteAddress:Integer; Function GetRemoteHost:String; Function Connect:Boolean; Function Write(Var Buff; Size:Integer):Integer; Function Read (Var Buff; Size:Integer):Integer; Function ReceiveLength:Integer; Constructor Create(Const Sock:Integer=Invalid_Socket); Destructor Destroy;Override; Property Host:String Read FHost Write FHost; Property Port:Word Read FPort Write FPort; Property CanRead:Boolean Read FCanRead; Property CanWrite:Boolean Read FCanWrite; Property Disconnected:Boolean Read FClose; Property ErrorPresent:Boolean Read FOnError; Property Error:Integer Read FError; End;
Function InetAddr(Addr:Integer):String;
implementation
Constructor TNewSock.Create; Begin Inherited Create; FClose:=Sock=Invalid_Socket; FSock:=Sock; {IF Not FClose Then Begin FCanWrite:=True; End Else} FCanWrite:=False; FCanRead:=False; FOnError:=False; FError:=0; End;
Destructor TNewSock.Destroy; Begin // Close; Inherited Destroy; End;
Procedure TNewSock.Close; Begin If FSock<>Invalid_Socket Then Begin If CloseSocket(FSock)<>0 Then Begin FError:=WSAGetLastError; FOnError:=True; End; FSock:=Invalid_Socket; FCanRead:=False; FCanWrite:=False; End; FClose:=True; End;
Procedure TNewSock.GetStatus; Var FD_READS,FD_WRITES,FD_ERROR:TFDSET; T:TTimeVal; R:Integer; Begin // If FClose Then Exit; T.tv_usec:=TimeOut Mod 1000; T.tv_sec:=TimeOut Div 1000; FD_ZERO(FD_READS); FD_SET(FSock,FD_READS); FD_WRITES:=FD_READS; FD_ERROR:=FD_READS;
//FD_SET(FSock,FD_WRITES);
R:=Select(1,@FD_READS,@FD_WRITES,@FD_ERROR,@T); If R=Socket_Error Then Begin FError:=WSAGetLastError; FOnError:=True; Exit; End Else FError:=0; If R>0 Then Begin If FD_ISSET(FSock,FD_READS) Then FCanRead:=True Else FCanRead:=False; If FD_ISSET(FSock,FD_WRITES) Then FCanWrite:=True; If FD_ISSET(FSock,FD_ERROR) Then Begin FOnError:=True; R:=SizeOf(FError); R:=GetSockOpt(FSock,SOL_SOCKET,SO_ERROR,@FError,R); {If R=SOCKET_ERROR Then FError:=WSAGetLastError;} End Else FOnError:=False; End; End;
Function TNewSock.GetRemoteAddress; Var _Addr:TSockAddr; _Size:Integer; Begin Result:=-1; If Not FClose Then Begin _Size:=SizeOf(_Addr); FError:=GetPeerName(FSock,_Addr,_Size); If FError=SOCKET_ERROR Then Begin FError:=WSAGetLastError; FOnError:=True; Exit; End; Result:=_Addr.sin_addr.S_addr; End; End;
Function TNewSock.GetRemoteHost; Var _Addr:Integer; Host:PHostEnt; Begin _Addr:=GetRemoteAddress; Host:=GetHostByAddr(@_Addr,SizeOf(_Addr),AF_INET); Result:=''; If Host<>Nil Then Result:=Host.h_name; End;
Function TNewSock.Write; Var R:Integer; Begin R:=Send(FSock,Buff,Size,0); If R=SOCKET_ERROR Then Begin FError:=WSAGetLastError; If FError=WSAEWOULDBLOCK Then Begin FCanWrite:=False; R:=0; FError:=0; End Else FOnError:=True; End; Result:=R; End;
Function TNewSock.Read; Var R:Integer; Begin R:=Recv(FSock,Buff,Size,0); If R=0 Then Close; If R=SOCKET_ERROR Then Begin FError:=WSAGetLastError; If FError=WSAEWOULDBLOCK Then Begin FCanRead:=False; FError:=0; End Else FOnError:=True; R:=0; End; Result:=R; End;
Function TNewSock.ReceiveLength; Begin If IOCTLSocket(FSock,FIONREAD,Result)=SOCKET_ERROR Then Begin FError:=WSAGetLastError; FOnError:=True; End; End;
Function TNewSock.Connect; Var PHost:PHostEnt; R:Integer; Begin Result:=False; If Not FClose Then Exit; If FHost='' Then Exit; If FPort=0 Then Exit; FSock:=Socket(AF_INET,SOCK_STREAM,IPPROTO_IP); If FSock=Invalid_Socket Then Begin FError:=WSAGetLastError; FOnError:=True; Close; Exit; End; FAddr.sin_family:=AF_INET; FAddr.sin_port:=HToNS(FPort); FAddr.sin_addr.S_addr:=Inet_addr(PChar(FHost)); If FAddr.sin_addr.S_addr=INADDR_NONE Then Begin PHost:=GetHostByName(PChar(FHost)); If PHost=Nil Then Begin FError:=WSAGetLastError; FOnError:=True; Exit; End; Move(PHost^.h_addr_list^[0], FAddr.sin_addr, PHost^.h_length); End; R:=WinSock.Connect(FSock,FAddr,SizeOF(FAddr)); If R=SOCKET_ERROR Then Begin FError:=WSAGetLastError; FOnError:=True; Exit; End; FClose:=False; Result:=True; End;
Function InetAddr; Var _Addr:TSockAddr; Begin _Addr.sin_addr.S_addr:=Addr; Result:=inet_ntoa(_Addr.sin_addr); End;
VAR WSAD:TWSAData;
Initialization Begin WSAStartup($202,WSAD); End;
Finalization Begin WSACleanup; End;
end.
-
Спасибо всем, буду пробовать!
|