MySocket.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:15k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit MySocket;
  2. interface
  3. uses
  4.   Windows,hxUDP,IdTCPClient,IdSocks,Dialogs,SysUtils,Forms;
  5. type
  6.   TMySocketCategory = (scUDP,scTCP);
  7.   TMySocket = class
  8.     public
  9.       ReceiverID:Integer;
  10.       MySocketCategory:TMySocketCategory;
  11.       ReceiverLocalIP   :String;     
  12.       ReceiverLocalPort :Integer;    
  13.       ReceiverIP        :String;     
  14.       ReceiverPort      :Integer;    
  15.       LocalIP           :String;     
  16.       LocalPort         :Integer;    
  17.       IP                :String;     
  18.       Port              :Integer;
  19.       RemoteAdd:String;
  20.       RemotePort:Integer;
  21.       constructor Create(ID:Integer;ClientTCP:TIdTCPClient;ForTalking:Boolean=False);
  22.       destructor Destroy;override;
  23.       procedure SendBuffer(var Buf; Size: Integer; MustUseTCP: Boolean=False);
  24.       procedure GetNATIPPort;
  25.       procedure BeginGetHole;
  26.       procedure KeepP2PSession;
  27.     private
  28.       IsForTalking:Boolean;
  29.       ClientUDPSocket:ThxUDPSocket;
  30.       ClientTCPSocket:TIdTCPClient;
  31.       procedure FUdpServerDataRead(UDPSocket: ThxUDPSocket;const PeerInfo: TPeerInfo);
  32.   end;
  33. implementation
  34. uses RealMessengerUnit,RealMessengerImpl,Global;
  35. procedure TMySocket.KeepP2PSession;
  36. var
  37.   skType:char;
  38. begin
  39.   try
  40.     GetNATIPPort;
  41.     if (MySocketCategory=scUDP) then
  42.     begin
  43.       skType:=#128;
  44.       ClientUDPSocket.SendBuf(skType,1,RemoteAdd,RemotePort);
  45.     end;
  46.   except
  47.   end;
  48. end;
  49. {------------------------------------------------------------------------------}
  50. procedure TMySocket.BeginGetHole;
  51. var
  52.   Buffer:Array[1..2048] of char;
  53.   CBPleaseCallMe:TCBPleaseCallMe;
  54.   StartTicket:Integer;
  55. begin
  56.   try
  57.     if (MySocketCategory=scUDP) then Exit;
  58.     StartTicket:=0;
  59.     while StartTicket<100 do
  60.     begin
  61.       if (IP<>'') and (Port<>0) then break;
  62.       Inc(StartTicket);
  63.       Application.ProcessMessages;
  64.       Sleep(30);
  65.     end;
  66.     CBPleaseCallMe.Receiver:=ReceiverID;
  67.     CBPleaseCallMe.Sender:=Me.ID;
  68.     CBPleaseCallMe.IP:=ReceiverIP;
  69.     CBPleaseCallMe.Port:=ReceiverPort;
  70.     CBPleaseCallMe.MyLocalIP:=LocalIP;
  71.     CBPleaseCallMe.MyLocalPort:=LocalPort;
  72.     CBPleaseCallMe.MyIP:=IP;
  73.     CBPleaseCallMe.MyPort:=Port;
  74.     try
  75.       CBPleaseCallMe.UseIP:=ReceiverLocalIP;
  76.       CBPleaseCallMe.UsePort:=ReceiverLocalPort;
  77.       Buffer[1]:=skPleaseCallMe;
  78.       CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
  79.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,ReceiverLocalIP,ReceiverLocalPort);
  80.       Sleep(50);
  81.     except
  82.     end;
  83.     try
  84.       CBPleaseCallMe.UseIP:=ReceiverIP;
  85.       CBPleaseCallMe.UsePort:=ReceiverPort;
  86.       Buffer[1]:=skPleaseCallMe;
  87.       CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
  88.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,ReceiverIP,ReceiverPort);
  89.       Sleep(50);
  90.     except
  91.     end;
  92.     CBPleaseCallMe.UseIP:=HostIP;
  93.     CBPleaseCallMe.UsePort:=ServerPort;
  94.     Buffer[1]:=skPleaseCallMe;
  95.     CopyMemory(@Buffer[2],@CBPleaseCallMe,SizeOf(CBPleaseCallMe));
  96.     ClientUDPSocket.SendBuf(Buffer,SizeOf(CBPleaseCallMe)+1,HostIP,ServerPort);
  97.   except
  98.   end;
  99.   //showmessage('BeginGetHole');
  100. end;
  101. {------------------------------------------------------------------------------}
  102. procedure TMySocket.SendBuffer(var Buf; Size: Integer; MustUseTCP: Boolean=False);
  103. begin
  104.   if (MySocketCategory=scTCP) or (MustUseTCP=True) then
  105.   begin
  106.     ClientTCPSocket.Socket.Send(Buf,Size);
  107.     //ActiveChatingForm.Caption:='TCP:'+IntToStr(GetTickCount);
  108.   end
  109.   else
  110.   begin
  111.     ClientUDPSocket.SendBuf(Buf,Size,RemoteAdd,RemotePort);
  112.     //ActiveChatingForm.Caption:='UDP:'+RemoteAdd+'('+IntToStr(RemotePort)+')';
  113.   end;
  114. end;
  115. {------------------------------------------------------------------------------}
  116. procedure TMySocket.GetNATIPPort;
  117. var
  118.   Buffer:Array[1..2048] of char;
  119.   CBGetMyIPAndPort:TCBGetMyIPAndPort;
  120. begin
  121.   try
  122.     if ReceiverID=0 then exit;
  123.     CBGetMyIPAndPort.Sender:=Me.ID;
  124.     CBGetMyIPAndPort.LocalIP:=LocalIP;
  125.     CBGetMyIPAndPort.LocalPort:=LocalPort;
  126.     CBGetMyIPAndPort.IP:='';
  127.     CBGetMyIPAndPort.Port:=0;
  128.     Buffer[1]:=skGetMyIPAndPort;
  129.     CopyMemory(@Buffer[2],@CBGetMyIPAndPort,SizeOf(CBGetMyIPAndPort));
  130.     ClientUDPSocket.SendBuf(Buffer,SizeOf(CBGetMyIPAndPort)+1,HostIP,ServerPort);
  131.   except
  132.   end;
  133. end;
  134. {------------------------------------------------------------------------------}
  135. constructor TMySocket.Create(ID:Integer;ClientTCP:TIdTCPClient;ForTalking:Boolean=False);
  136. begin
  137.   ReceiverID:=ID;
  138.   ClientTCPSocket:=ClientTCP;
  139.   IsForTalking:=ForTalking;
  140.   MySocketCategory:=scTCP;
  141.   ReceiverLocalIP   :='';
  142.   ReceiverLocalPort :=0;
  143.   ReceiverIP        :='';
  144.   ReceiverPort      :=0;
  145.   LocalIP           :='';
  146.   LocalPort         :=0;
  147.   IP                :='';
  148.   Port              :=0;
  149.   RemoteAdd         :='';
  150.   RemotePort        :=0;
  151.   try
  152.     ClientUDPSocket:=ThxUDPSocket.Create;
  153.     ClientUDPSocket.OnDataRead:=FUdpServerDataRead;
  154.     ClientUDPSocket.Port:=0;
  155.     if ProxyCategory=pcSocks5 then
  156.     with ClientUDPSocket.ProxyInfo do
  157.     begin
  158.       Enabled:=True;
  159.       Address:=ProxyAddress;
  160.       Port:=ProxyPort;
  161.       Username:=ProxyUsername;
  162.       Password:=ProxyPassword;
  163.     end;
  164.     ClientUDPSocket.Active:=True;
  165.     LocalIP:=GetHostIP('');
  166.     LocalPort:=ClientUDPSocket.Port;
  167.     GetNATIPPort;
  168.     MySockets.Add(Self);
  169.   except
  170.   end;
  171. end;
  172. {------------------------------------------------------------------------------}
  173. destructor TMySocket.Destroy;
  174. begin
  175.   try
  176.     ClientUDPSocket.Active:=False;
  177.   finally
  178.     ClientUDPSocket.Free;
  179.   end;
  180.   MySockets.Remove(Self);
  181. end;
  182. {------------------------------------------------------------------------------}
  183. procedure TMySocket.FUdpServerDataRead(UDPSocket: ThxUDPSocket; const PeerInfo: TPeerInfo);
  184. var
  185.   skType:Char;
  186.   ReceiverBuffer:array[1..2048] of char;
  187.   Buffer:array[1..2048] of char;
  188.   
  189.   CBGetMyIPAndPort:TCBGetMyIPAndPort;
  190.   CBPleaseCallMe:TCBPleaseCallMe;
  191.   CBCallSomeone:TCBCallSomeone;
  192.   CBP2PResponse,CBP2PResponse2:TCBP2PResponse;
  193.   CBCalled:TCBCalled;
  194.   CBAudio:TCBAudio;
  195.   CBVideo:TCBVideo;
  196.   CBSendFilePackage:TCBSendFilePackage;
  197.   CBSendFileResult:TCBSendFileResult;
  198.   CBInputing:TCBInputing;
  199.   CBMessage:TCBMessage;
  200.   CBReturnMessage:TCBReturnMessage;
  201.   CBBeginTalk:TCBBeginTalk;
  202.   PortChanged:Boolean;
  203. begin
  204.   if UDPSocket.RecvBuf(ReceiverBuffer, SizeOf(ReceiverBuffer), PeerInfo.PeerIP, PeerInfo.PeerPort) then
  205.   begin
  206.     skType:=ReceiverBuffer[1];
  207.     {**************************************************************************}
  208.     if skType = skGetMyIPAndPort then
  209.     begin
  210.       CopyMemory(@CBGetMyIPAndPort,@ReceiverBuffer[2],SizeOf(CBGetMyIPAndPort));
  211.       if CBGetMyIPAndPort.Sender=Me.ID then
  212.       begin
  213.         IP:=CBGetMyIPAndPort.IP;
  214.         PortChanged:=False;
  215.         if Port<>CBGetMyIPAndPort.Port then
  216.         begin
  217.           Port:=CBGetMyIPAndPort.Port;
  218.           PortChanged:=True;
  219.         end;
  220.         if IsForTalking and PortChanged then
  221.         begin
  222.           CBBeginTalk.Receiver:=ReceiverID;
  223.           CBBeginTalk.Sender:=Me.ID;
  224.           CBBeginTalk.LocalIP:=LocalIP;
  225.           CBBeginTalk.LocalPort:=LocalPort;
  226.           CBBeginTalk.IP:=IP;
  227.           CBBeginTalk.Port:=Port;
  228.           Buffer[1]:=skBeginTalk;
  229.           CopyMemory(@Buffer[2],@CBBeginTalk,SizeOf(CBBeginTalk));
  230.           SendBuffer(Buffer,SizeOf(CBBeginTalk)+1,True);
  231.         end;
  232.       end;
  233.       Exit;
  234.     end;
  235.     {**************************************************************************}
  236.     if skType = skPleaseCallMe then
  237.     begin
  238.       CopyMemory(@CBPleaseCallMe,@ReceiverBuffer[2],SizeOf(CBPleaseCallMe));
  239.       if CBPleaseCallMe.Sender<>ReceiverID then Exit;
  240.       if ((PeerInfo.PeerIP<>HostIP) and (PeerInfo.PeerPort<>ServerPort)) then
  241.       begin
  242.         CBP2PResponse2.Receiver:=ReceiverID;
  243.         CBP2PResponse2.Sender:=Me.ID;
  244.         CBP2PResponse2.IP:=ReceiverIP;
  245.         CBP2PResponse2.Port:=ReceiverPort;
  246.         CBP2PResponse2.PeerIP:=CBPleaseCallMe.UseIP;
  247.         CBP2PResponse2.PeerPort:=CBPleaseCallMe.UsePort;
  248.         CBP2PResponse2.UseIP:=PeerInfo.PeerIP;
  249.         CBP2PResponse2.UsePort:=PeerInfo.PeerPort;
  250.         Buffer[1]:=skP2PResponse;
  251.         CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
  252.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
  253.         Sleep(50);
  254.               
  255.         CBP2PResponse2.UseIP:=HostIP;
  256.         CBP2PResponse2.UsePort:=ServerPort;
  257.         Buffer[1]:=skP2PResponse;
  258.         CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
  259.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
  260.         Exit;
  261.       end;
  262.       ReceiverLocalIP:=CBPleaseCallMe.MyLocalIP;
  263.       ReceiverLocalPort:=CBPleaseCallMe.MyLocalPort;
  264.       ReceiverIP:=CBPleaseCallMe.MyIP;
  265.       ReceiverPort:=CBPleaseCallMe.MyPort;
  266.       CBCallSomeone.Receiver:=ReceiverID;
  267.       CBCallSomeone.Sender:=Me.ID;
  268.       CBCallSomeone.IP:=ReceiverLocalIP;
  269.       CBCallSomeone.Port:=ReceiverLocalPort;
  270.       Buffer[1]:=skCallSomeone;
  271.       CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
  272.       try
  273.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverLocalIP,ReceiverLocalPort);
  274.         Sleep(50);
  275.       except
  276.       end;
  277.       CBCallSomeone.Receiver:=ReceiverID;
  278.       CBCallSomeone.Sender:=Me.ID;
  279.       CBCallSomeone.IP:=ReceiverIP;
  280.       CBCallSomeone.Port:=ReceiverPort;
  281.       Buffer[1]:=skCallSomeone;
  282.       CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
  283.       try
  284.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverIP,ReceiverPort);
  285.         Sleep(50);
  286.       except
  287.       end;
  288.       CBCalled.Receiver:=ReceiverID;
  289.       CBCalled.Sender:=Me.ID;
  290.       CBCalled.IP:=ReceiverIP;
  291.       CBCalled.Port:=ReceiverPort;
  292.       Buffer[1]:=skCalled;
  293.       CopyMemory(@Buffer[2],@CBCalled,SizeOf(CBCalled));
  294.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCalled)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
  295.       Sleep(50);
  296.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCalled)+1,HostIP,ServerPort);
  297.       Exit;
  298.     end;
  299.     {**************************************************************************}
  300.     if skType = skCalled then
  301.     begin
  302.       CopyMemory(@CBCalled,@ReceiverBuffer[2],SizeOf(CBCalled));
  303.       if CBCalled.Sender<>ReceiverID then Exit;
  304.       CBCallSomeone.Receiver:=ReceiverID;
  305.       CBCallSomeone.Sender:=Me.ID;
  306.       CBCallSomeone.IP:=ReceiverLocalIP;
  307.       CBCallSomeone.Port:=ReceiverLocalPort;
  308.       Buffer[1]:=skCallSomeone;
  309.       CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
  310.       try
  311.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverLocalIP,ReceiverLocalPort);
  312.         Sleep(50);
  313.       except
  314.       end;
  315.       CBCallSomeone.Receiver:=ReceiverID;
  316.       CBCallSomeone.Sender:=Me.ID;
  317.       CBCallSomeone.IP:=ReceiverIP;
  318.       CBCallSomeone.Port:=ReceiverPort;
  319.       Buffer[1]:=skCallSomeone;
  320.       CopyMemory(@Buffer[2],@CBCallSomeone,SizeOf(CBCallSomeone));
  321.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBCallSomeone)+1,ReceiverIP,ReceiverPort);
  322.       Exit;
  323.    end;
  324.     {**************************************************************************}
  325.     if skType = skCallSomeone then
  326.     begin
  327.       CopyMemory(@CBCallSomeone,@ReceiverBuffer[2],SizeOf(CBCallSomeone));
  328.       if CBCallSomeone.Sender<>ReceiverID then Exit;
  329.       CBP2PResponse.Receiver:=ReceiverID;
  330.       CBP2PResponse.Sender:=Me.ID;
  331.       CBP2PResponse.IP:=ReceiverIP;
  332.       CBP2PResponse.Port:=ReceiverPort;
  333.       CBP2PResponse.PeerIP:=CBCallSomeone.IP;
  334.       CBP2PResponse.PeerPort:=CBCallSomeone.Port;
  335.       CBP2PResponse.UseIP:=PeerInfo.PeerIP;
  336.       CBP2PResponse.UsePort:=PeerInfo.PeerPort;
  337.       Buffer[1]:=skP2PResponse;
  338.       CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
  339.       try
  340.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);
  341.         Sleep(50);
  342.       except
  343.       end;
  344.       CBP2PResponse.UseIP:=HostIP;
  345.       CBP2PResponse.UsePort:=ServerPort;
  346.       Buffer[1]:=skP2PResponse;
  347.       CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
  348.       ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
  349.       Exit;
  350.     end;
  351.     {**************************************************************************}
  352.     if skType = skP2PResponse then
  353.     begin
  354.       CopyMemory(@CBP2PResponse,@ReceiverBuffer[2],SizeOf(CBP2PResponse));
  355.       if CBP2PResponse.Sender<>ReceiverID then Exit;
  356.       if MySocketCategory=scUDP then Exit;
  357.       
  358.       MySocketCategory:=scUDP;
  359.       RemoteAdd:=CBP2PResponse.PeerIP;
  360.       RemotePort:=CBP2PResponse.PeerPort;
  361.       if ((PeerInfo.PeerIP<>HostIP) and (PeerInfo.PeerPort<>ServerPort)) then
  362.       begin
  363.         CBP2PResponse2.Receiver:=ReceiverID;
  364.         CBP2PResponse2.Sender:=Me.ID;
  365.         CBP2PResponse2.IP:=ReceiverIP;
  366.         CBP2PResponse2.Port:=ReceiverPort;
  367.         CBP2PResponse2.PeerIP:=CBP2PResponse.UseIP;
  368.         CBP2PResponse2.PeerPort:=CBP2PResponse.UsePort;
  369.         CBP2PResponse2.UseIP:=PeerInfo.PeerIP;
  370.         CBP2PResponse2.UsePort:=PeerInfo.PeerPort;
  371.         Buffer[1]:=skP2PResponse;
  372.         CopyMemory(@Buffer[2],@CBP2PResponse,SizeOf(CBP2PResponse));
  373.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,PeerInfo.PeerIP,PeerInfo.PeerPort);        
  374.         Sleep(50);        
  375.         ClientUDPSocket.SendBuf(Buffer,SizeOf(CBP2PResponse)+1,HostIP,ServerPort);
  376.       end;
  377.        
  378.       Exit;
  379.     end;
  380.     
  381.     {************************************************************************}
  382.     if skType = skInputing then
  383.     begin
  384.       CopyMemory(@CBInputing,@ReceiverBuffer[2],SizeOf(CBInputing));
  385.       RealMessengerX.ProcessCBInputing(CBInputing);
  386.       Exit;
  387.     end;
  388.     {************************************************************************}
  389.     if skType = skMessage then
  390.     begin
  391.       CopyMemory(@CBMessage,@ReceiverBuffer[2],SizeOf(CBMessage));
  392.       RealMessengerX.ProcessCBMessage(CBMessage);
  393.       Exit;
  394.     end;
  395.     {************************************************************************}
  396.     if skType = skReturnMessage then
  397.     begin
  398.       CopyMemory(@CBReturnMessage,@ReceiverBuffer[2],SizeOf(CBReturnMessage));
  399.       RealMessengerX.ProcessCBReturnMessage(CBReturnMessage);
  400.       Exit;
  401.     end;
  402.     {**************************************************************************}
  403.     if skType = skAudio then
  404.     begin
  405.       CopyMemory(@CBAudio,@ReceiverBuffer[2],SizeOf(CBAudio));
  406.       RealMessengerX.ProcessCBAudio(CBAudio);
  407.       Exit;
  408.     end;
  409.     {**************************************************************************}
  410.     if skType = skVideo then
  411.     begin
  412.       CopyMemory(@CBVideo,@ReceiverBuffer[2],SizeOf(CBVideo));
  413.       RealMessengerX.ProcessCBVideo(CBVideo);
  414.       Exit;
  415.     end;
  416.     
  417.     {**************************************************************************}
  418.     if skType = skSendFilePackage then
  419.     begin
  420.       CopyMemory(@CBSendFilePackage,@ReceiverBuffer[2],SizeOf(CBSendFilePackage));
  421.       RealMessengerX.ProcessCBSendFilePackage(CBSendFilePackage);
  422.       Exit;
  423.     end;
  424.     
  425.     {************************************************************************}
  426.     if skType = skSendFileResult then 
  427.     begin
  428.       CopyMemory(@CBSendFileResult,@ReceiverBuffer[2],SizeOf(CBSendFileResult));
  429.       RealMessengerX.ProcessCBSendFileResult(CBSendFileResult);
  430.       Exit;
  431.     end;
  432.     
  433.   end;
  434. end;
  435. end.