MySocket.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:15k
- unit MySocket;
- interface
- uses
- Windows,hxUDP,IdTCPClient,IdSocks,Dialogs,SysUtils,Forms;
- type
- TMySocketCategory = (scUDP,scTCP);
- TMySocket = class
- public
- ReceiverID:Integer;
- MySocketCategory:TMySocketCategory;
- ReceiverLocalIP :String;
- ReceiverLocalPort :Integer;
- ReceiverIP :String;
- ReceiverPort :Integer;
- LocalIP :String;
- LocalPort :Integer;
- IP :String;
- Port :Integer;
- RemoteAdd:String;
- RemotePort:Integer;
- constructor Create(ID:Integer;ClientTCP:TIdTCPClient;ForTalking:Boolean=False);
- destructor Destroy;override;
- procedure SendBuffer(var Buf; Size: Integer; MustUseTCP: Boolean=False);
- procedure GetNATIPPort;
- procedure BeginGetHole;
- procedure KeepP2PSession;
- private
- IsForTalking:Boolean;
- ClientUDPSocket:ThxUDPSocket;
- ClientTCPSocket:TIdTCPClient;
- procedure FUdpServerDataRead(UDPSocket: ThxUDPSocket;const PeerInfo: TPeerInfo);
- end;
- implementation
- uses RealMessengerUnit,RealMessengerImpl,Global;
- procedure TMySocket.KeepP2PSession;
- var
- skType:char;
- begin
- try
- GetNATIPPort;
- if (MySocketCategory=scUDP) then
- begin
- skType:=#128;
- ClientUDPSocket.SendBuf(skType,1,RemoteAdd,RemotePort);
- end;
- except
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TMySocket.BeginGetHole;
- var
- Buffer:Array[1..2048] of char;
- CBPleaseCallMe:TCBPleaseCallMe;
- StartTicket:Integer;
- begin
- try
- if (MySocketCategory=scUDP) then Exit;
- StartTicket:=0;
- while StartTicket<100 do
- begin
- if (IP<>'') and (Port<>0) then break;
- Inc(StartTicket);
- Application.ProcessMessages;
- Sleep(30);
- end;
- CBPleaseCallMe.Receiver:=ReceiverID;
- CBPleaseCallMe.Sender:=Me.ID;
- CBPleaseCallMe.IP:=ReceiverIP;
- CBPleaseCallMe.Port:=ReceiverPort;
- CBPleaseCallMe.MyLocalIP:=LocalIP;
- CBPleaseCallMe.MyLocalPort:=LocalPort;
- CBPleaseCallMe.MyIP:=IP;
- CBPleaseCallMe.MyPort:=Port;
- try
- CBPleaseCallMe.UseIP:=ReceiverLocalIP;
- CBPleaseCallMe.UsePort:=ReceiverLocalPort;
- Buffer[1]:=skPleaseCallMe;
- CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,ReceiverLocalIP,ReceiverLocalPort);
- Sleep(50);
- except
- end;
- try
- CBPleaseCallMe.UseIP:=ReceiverIP;
- CBPleaseCallMe.UsePort:=ReceiverPort;
- Buffer[1]:=skPleaseCallMe;
- CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,ReceiverIP,ReceiverPort);
- Sleep(50);
- except
- end;
- CBPleaseCallMe.UseIP:=HostIP;
- CBPleaseCallMe.UsePort:=ServerPort;
- Buffer[1]:=skPleaseCallMe;
- CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,HostIP,ServerPort);
- except
- end;
- //showmessage('BeginGetHole');
- end;
- {------------------------------------------------------------------------------}
- procedure TMySocket.SendBuffer(var Buf; Size: Integer; MustUseTCP: Boolean=False);
- begin
- if (MySocketCategory=scTCP) or (MustUseTCP=True) then
- begin
- ClientTCPSocket.Socket.Send(Buf,Size);
- //ActiveChatingForm.Caption:='TCP:'+IntToStr(GetTickCount);
- end
- else
- begin
- ClientUDPSocket.SendBuf(Buf,Size,RemoteAdd,RemotePort);
- //ActiveChatingForm.Caption:='UDP:'+RemoteAdd+'('+IntToStr(RemotePort)+')';
- end;
- end;
- {------------------------------------------------------------------------------}
- procedure TMySocket.GetNATIPPort;
- var
- Buffer:Array[1..2048] of char;
- CBGetMyIPAndPort:TCBGetMyIPAndPort;
- begin
- try
- if ReceiverID=0 then exit;
- CBGetMyIPAndPort.Sender:=Me.ID;
- CBGetMyIPAndPort.LocalIP:=LocalIP;
- CBGetMyIPAndPort.LocalPort:=LocalPort;
- CBGetMyIPAndPort.IP:='';
- CBGetMyIPAndPort.Port:=0;
- Buffer[1]:=skGetMyIPAndPort;
- CopyMemory(@Buffer[2],@CBGetMyIPAndPort,SizeOf(CBGetMyIPAndPort));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBGetMyIPAndPort)+1,HostIP,ServerPort);
- except
- end;
- end;
- {------------------------------------------------------------------------------}
- constructor TMySocket.Create(ID:Integer;ClientTCP:TIdTCPClient;ForTalking:Boolean=False);
- begin
- ReceiverID:=ID;
- ClientTCPSocket:=ClientTCP;
- IsForTalking:=ForTalking;
- MySocketCategory:=scTCP;
- ReceiverLocalIP :='';
- ReceiverLocalPort :=0;
- ReceiverIP :='';
- ReceiverPort :=0;
- LocalIP :='';
- LocalPort :=0;
- IP :='';
- Port :=0;
- RemoteAdd :='';
- RemotePort :=0;
- try
- ClientUDPSocket:=ThxUDPSocket.Create;
- ClientUDPSocket.OnDataRead:=FUdpServerDataRead;
- ClientUDPSocket.Port:=0;
- if ProxyCategory=pcSocks5 then
- with ClientUDPSocket.ProxyInfo do
- begin
- Enabled:=True;
- Address:=ProxyAddress;
- Port:=ProxyPort;
- Username:=ProxyUsername;
- Password:=ProxyPassword;
- end;
- ClientUDPSocket.Active:=True;
- LocalIP:=GetHostIP('');
- LocalPort:=ClientUDPSocket.Port;
- GetNATIPPort;
- MySockets.Add(Self);
- except
- end;
- end;
- {------------------------------------------------------------------------------}
- destructor TMySocket.Destroy;
- begin
- try
- ClientUDPSocket.Active:=False;
- finally
- ClientUDPSocket.Free;
- end;
- MySockets.Remove(Self);
- end;
- {------------------------------------------------------------------------------}
- procedure TMySocket.FUdpServerDataRead(UDPSocket: ThxUDPSocket; const PeerInfo: TPeerInfo);
- var
- skType:Char;
- ReceiverBuffer:array[1..2048] of char;
- Buffer:array[1..2048] of char;
-
- CBGetMyIPAndPort:TCBGetMyIPAndPort;
- CBPleaseCallMe:TCBPleaseCallMe;
- CBCallSomeone:TCBCallSomeone;
- CBP2PResponse,CBP2PResponse2:TCBP2PResponse;
- CBCalled:TCBCalled;
- CBAudio:TCBAudio;
- CBVideo:TCBVideo;
- CBSendFilePackage:TCBSendFilePackage;
- CBSendFileResult:TCBSendFileResult;
- CBInputing:TCBInputing;
- CBMessage:TCBMessage;
- CBReturnMessage:TCBReturnMessage;
- CBBeginTalk:TCBBeginTalk;
- PortChanged:Boolean;
- begin
- if UDPSocket.RecvBuf(ReceiverBuffer, SizeOf(ReceiverBuffer), PeerInfo.PeerIP, PeerInfo.PeerPort) then
- begin
- skType:=ReceiverBuffer[1];
- {**************************************************************************}
- if skType = skGetMyIPAndPort then
- begin
- CopyMemory(@CBGetMyIPAndPort,@ReceiverBuffer[2],SizeOf(CBGetMyIPAndPort));
- if CBGetMyIPAndPort.Sender=Me.ID then
- begin
- IP:=CBGetMyIPAndPort.IP;
- PortChanged:=False;
- if Port<>CBGetMyIPAndPort.Port then
- begin
- Port:=CBGetMyIPAndPort.Port;
- PortChanged:=True;
- end;
- if IsForTalking and PortChanged then
- begin
- CBBeginTalk.Receiver:=ReceiverID;
- CBBeginTalk.Sender:=Me.ID;
- CBBeginTalk.LocalIP:=LocalIP;
- CBBeginTalk.LocalPort:=LocalPort;
- CBBeginTalk.IP:=IP;
- CBBeginTalk.Port:=Port;
- Buffer[1]:=skBeginTalk;
- CopyMemory(@Buffer[2],@CBBeginTalk,SizeOf(CBBeginTalk));
- SendBuffer(Buffer,SizeOf(CBBeginTalk)+1,True);
- end;
- end;
- Exit;
- end;
- {**************************************************************************}
- if skType = skPleaseCallMe then
- begin
- CopyMemory(@CBPleaseCallMe,@ReceiverBuffer[2],SizeOf(CBPleaseCallMe));
- if CBPleaseCallMe.Sender<>ReceiverID then Exit;
- if ((PeerInfo.PeerIP<>HostIP) and (PeerInfo.PeerPort<>ServerPort)) then
- begin
- CBP2PResponse2.Receiver:=ReceiverID;
- CBP2PResponse2.Sender:=Me.ID;
- CBP2PResponse2.IP:=ReceiverIP;
- CBP2PResponse2.Port:=ReceiverPort;
- CBP2PResponse2.PeerIP:=CBPleaseCallMe.UseIP;
- CBP2PResponse2.PeerPort:=CBPleaseCallMe.UsePort;
- CBP2PResponse2.UseIP:=PeerInfo.PeerIP;
- CBP2PResponse2.UsePort:=PeerInfo.PeerPort;
- Buffer[1]:=skP2PResponse;
- CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
- Sleep(50);
-
- CBP2PResponse2.UseIP:=HostIP;
- CBP2PResponse2.UsePort:=ServerPort;
- Buffer[1]:=skP2PResponse;
- CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
- Exit;
- end;
- ReceiverLocalIP:=CBPleaseCallMe.MyLocalIP;
- ReceiverLocalPort:=CBPleaseCallMe.MyLocalPort;
- ReceiverIP:=CBPleaseCallMe.MyIP;
- ReceiverPort:=CBPleaseCallMe.MyPort;
- CBCallSomeone.Receiver:=ReceiverID;
- CBCallSomeone.Sender:=Me.ID;
- CBCallSomeone.IP:=ReceiverLocalIP;
- CBCallSomeone.Port:=ReceiverLocalPort;
- Buffer[1]:=skCallSomeone;
- CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
- try
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverLocalIP,ReceiverLocalPort);
- Sleep(50);
- except
- end;
- CBCallSomeone.Receiver:=ReceiverID;
- CBCallSomeone.Sender:=Me.ID;
- CBCallSomeone.IP:=ReceiverIP;
- CBCallSomeone.Port:=ReceiverPort;
- Buffer[1]:=skCallSomeone;
- CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
- try
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverIP,ReceiverPort);
- Sleep(50);
- except
- end;
- CBCalled.Receiver:=ReceiverID;
- CBCalled.Sender:=Me.ID;
- CBCalled.IP:=ReceiverIP;
- CBCalled.Port:=ReceiverPort;
- Buffer[1]:=skCalled;
- CopyMemory(@Buffer[2],@CBCalled,SizeOf(CBCalled));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCalled)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
- Sleep(50);
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCalled)+1,HostIP,ServerPort);
- Exit;
- end;
- {**************************************************************************}
- if skType = skCalled then
- begin
- CopyMemory(@CBCalled,@ReceiverBuffer[2],SizeOf(CBCalled));
- if CBCalled.Sender<>ReceiverID then Exit;
- CBCallSomeone.Receiver:=ReceiverID;
- CBCallSomeone.Sender:=Me.ID;
- CBCallSomeone.IP:=ReceiverLocalIP;
- CBCallSomeone.Port:=ReceiverLocalPort;
- Buffer[1]:=skCallSomeone;
- CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
- try
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverLocalIP,ReceiverLocalPort);
- Sleep(50);
- except
- end;
- CBCallSomeone.Receiver:=ReceiverID;
- CBCallSomeone.Sender:=Me.ID;
- CBCallSomeone.IP:=ReceiverIP;
- CBCallSomeone.Port:=ReceiverPort;
- Buffer[1]:=skCallSomeone;
- CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverIP,ReceiverPort);
- Exit;
- end;
- {**************************************************************************}
- if skType = skCallSomeone then
- begin
- CopyMemory(@CBCallSomeone,@ReceiverBuffer[2],SizeOf(CBCallSomeone));
- if CBCallSomeone.Sender<>ReceiverID then Exit;
- CBP2PResponse.Receiver:=ReceiverID;
- CBP2PResponse.Sender:=Me.ID;
- CBP2PResponse.IP:=ReceiverIP;
- CBP2PResponse.Port:=ReceiverPort;
- CBP2PResponse.PeerIP:=CBCallSomeone.IP;
- CBP2PResponse.PeerPort:=CBCallSomeone.Port;
- CBP2PResponse.UseIP:=PeerInfo.PeerIP;
- CBP2PResponse.UsePort:=PeerInfo.PeerPort;
- Buffer[1]:=skP2PResponse;
- CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
- try
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
- Sleep(50);
- except
- end;
- CBP2PResponse.UseIP:=HostIP;
- CBP2PResponse.UsePort:=ServerPort;
- Buffer[1]:=skP2PResponse;
- CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
- Exit;
- end;
- {**************************************************************************}
- if skType = skP2PResponse then
- begin
- CopyMemory(@CBP2PResponse,@ReceiverBuffer[2],SizeOf(CBP2PResponse));
- if CBP2PResponse.Sender<>ReceiverID then Exit;
- if MySocketCategory=scUDP then Exit;
-
- MySocketCategory:=scUDP;
- RemoteAdd:=CBP2PResponse.PeerIP;
- RemotePort:=CBP2PResponse.PeerPort;
- if ((PeerInfo.PeerIP<>HostIP) and (PeerInfo.PeerPort<>ServerPort)) then
- begin
- CBP2PResponse2.Receiver:=ReceiverID;
- CBP2PResponse2.Sender:=Me.ID;
- CBP2PResponse2.IP:=ReceiverIP;
- CBP2PResponse2.Port:=ReceiverPort;
- CBP2PResponse2.PeerIP:=CBP2PResponse.UseIP;
- CBP2PResponse2.PeerPort:=CBP2PResponse.UsePort;
- CBP2PResponse2.UseIP:=PeerInfo.PeerIP;
- CBP2PResponse2.UsePort:=PeerInfo.PeerPort;
- Buffer[1]:=skP2PResponse;
- CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
- Sleep(50);
- ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
- end;
-
- Exit;
- end;
-
- {************************************************************************}
- if skType = skInputing then
- begin
- CopyMemory(@CBInputing,@ReceiverBuffer[2],SizeOf(CBInputing));
- RealMessengerX.ProcessCBInputing(CBInputing);
- Exit;
- end;
- {************************************************************************}
- if skType = skMessage then
- begin
- CopyMemory(@CBMessage,@ReceiverBuffer[2],SizeOf(CBMessage));
- RealMessengerX.ProcessCBMessage(CBMessage);
- Exit;
- end;
- {************************************************************************}
- if skType = skReturnMessage then
- begin
- CopyMemory(@CBReturnMessage,@ReceiverBuffer[2],SizeOf(CBReturnMessage));
- RealMessengerX.ProcessCBReturnMessage(CBReturnMessage);
- Exit;
- end;
- {**************************************************************************}
- if skType = skAudio then
- begin
- CopyMemory(@CBAudio,@ReceiverBuffer[2],SizeOf(CBAudio));
- RealMessengerX.ProcessCBAudio(CBAudio);
- Exit;
- end;
- {**************************************************************************}
- if skType = skVideo then
- begin
- CopyMemory(@CBVideo,@ReceiverBuffer[2],SizeOf(CBVideo));
- RealMessengerX.ProcessCBVideo(CBVideo);
- Exit;
- end;
-
- {**************************************************************************}
- if skType = skSendFilePackage then
- begin
- CopyMemory(@CBSendFilePackage,@ReceiverBuffer[2],SizeOf(CBSendFilePackage));
- RealMessengerX.ProcessCBSendFilePackage(CBSendFilePackage);
- Exit;
- end;
-
- {************************************************************************}
- if skType = skSendFileResult then
- begin
- CopyMemory(@CBSendFileResult,@ReceiverBuffer[2],SizeOf(CBSendFileResult));
- RealMessengerX.ProcessCBSendFileResult(CBSendFileResult);
- Exit;
- end;
-
- end;
- end;
- end.