MainUnit.pas
上传用户:xgd119
上传日期:2007-05-02
资源大小:514k
文件大小:7k
源码类别:

P2P编程

开发平台:

Delphi

  1. unit MainUnit;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.   Dialogs, StdCtrls, IdBaseComponent, IdSocketHandle,IdComponent,
  6.   IdUDPBase, IdUDPServer,testQQCommon;
  7. type
  8.   TServer = class(TForm)
  9.     UDPServer: TIdUDPServer;
  10.     Button1: TButton;
  11.     Memo1: TMemo;
  12.     procedure Button1Click(Sender: TObject);
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure UDPServerUDPRead(Sender: TObject; AData: TStream;ABinding: TIdSocketHandle);
  15.     procedure StartUp;
  16.   private
  17.     { Private declarations }
  18.   public
  19.     { Public declarations }
  20.     OnlineUsers:TStringList; //在线用户列表
  21.     function ProcRecvLogonData(ThisBinding:TIdSocketHandle;LogonData:TLogonData):boolean;
  22.     function ProcRecvLogoutData(ThisBinding:TIdSocketHandle;LogoutData:TLogoutData):boolean;
  23.     function ProcRecvP2PData(ThisBinding:TIdSocketHandle;HandData:THandData):boolean;
  24.   end;
  25. var
  26.   Server: TServer;
  27. implementation
  28. {$R *.dfm}
  29. procedure TServer.Button1Click(Sender: TObject);
  30. begin
  31.    Server.Close ;
  32. end;
  33. procedure TServer.FormCreate(Sender: TObject);
  34. begin
  35.    StartUp;
  36.    Hide;
  37. end;
  38. //启动服务程序
  39. procedure TServer.StartUp;
  40. var   bind:TIdSocketHandle;
  41. begin
  42. try
  43.    OnlineUsers:=TStringList.create;
  44.    UDPServer.DefaultPort :=SERVER_Port;
  45.    udpserver.Active :=true;
  46.    Memo1.Lines.Add('服务已经在 ['+IntToStr(SERVER_Port)+'] 端口启动!');
  47.  except on E:Exception do
  48.     Memo1.lines.add(e.Message );
  49.  end;
  50. end;
  51. procedure TServer.UDPServerUDPRead(Sender: TObject; AData: TStream;ABinding: TIdSocketHandle);
  52. var _UDPHead:TTQQUDPHead;
  53.     _LogonData:TLogonData;
  54.     _LogoutData:TLogoutData;
  55.     _HandData:THandData;
  56.     RecvSize,MsgType:integer;
  57. begin
  58. try
  59.    MsgType:=-1;
  60.    RecvSize:=adata.Read (_UDPHead,sizeof(_UDPHead) );  //接收数据头
  61.    MsgType:=StrToInt(_UDPHead.MsgType);
  62.    if Msgtype=-1 then exit;
  63. //   UDPSERVER.Binding.Assign(ABinding); //2005-02-17 Updated!
  64.    case  MsgType of
  65.      LogonSign:
  66.      begin
  67.        //登录
  68.        Adata.Read(_LogonData,sizeof(TLogonData));
  69.        ProcRecvLogonData(Abinding,_LogonData);
  70.      end;
  71.      LogoutSign:
  72.      begin
  73.        //注销
  74.        Adata.Read(_LogoutData,sizeof(TLogoutData));
  75.        ProcRecvLogoutData(Abinding,_LogoutData);
  76.      end;
  77.      HandSign:
  78.      begin
  79.        //处理P2P请求
  80.        Adata.Read(_HandData,sizeof(THandData));
  81.        ProcRecvP2PData(Abinding,_HandData);
  82.      end;
  83.    end;
  84.   except on E:Exception do
  85.      Memo1.lines.add(E.Message);
  86.   end;
  87. end;
  88. //登录处理
  89. function Tserver.ProcRecvLogonData(ThisBinding:TIdSocketHandle;LogonData:TLogonData):boolean;
  90. var _LogonDataPackage:TLogonDataPackage;
  91.     _HandDataPackage:THandDataPackage;
  92.     _FriendDataPackage:TFriendDataPackage;
  93.     _tempUserBasicInfo:TServerUserBasicInfo;
  94.     _Account,_PeerIP,_tempIP,_NeedReBack:string;
  95.     i,_PeerPORT,_tempPORT:integer;
  96. begin
  97.    _Account:=LogonData.Account;
  98.    _PeerIP:=thisbinding.PeerIP ;
  99.    _PeerPORT:=thisbinding.PeerPort ;
  100.    with  _LogonDataPackage do
  101.    begin
  102.      Head.MsgType:=IntToStr(LogonSign);
  103.      StrPCopy(Body.Account,_Account);
  104.      StrPCopy(Body.MyPublicIP,_PeerIP);
  105.      StrPCopy(Body.MyPublicPORT,IntToStr(_PeerPORT));
  106.      StrPCopy(Body.lResult,IsTrue);
  107.    end;
  108.    //返回自己的登录信息
  109.    UdpServer.SendBuffer(_PeerIP,_PeerPort ,_LogonDataPackage,sizeof(_LogonDataPackage));
  110.    sleep(1);
  111.    for i:=0 to OnlineUsers.Count-1 do
  112.    begin
  113.      _tempUserBasicInfo:=TServerUserBasicInfo(Onlineusers.Objects[i]);
  114.      _tempIP:=_tempUserBasicInfo.UserData.IP;
  115.      _tempPORT:=StrToInt(_tempUserBasicInfo.UserData.PORT);
  116.      with _HandDataPackage do
  117.      begin
  118.         Head.MsgType:=IntToStr(HandSign);
  119.           StrPCopy(Body.Account,_Account);
  120.           StrPCopy(Body.Mark,IsTrue);
  121.           StrPCopy(Body.DesIP,_PeerIP);
  122.           StrPCopy(Body.DesPORT,IntToStr(_PeerPort));
  123.           StrPCopy(Body.NeedReBack,IsTrue);
  124.         //Head.DataSize:=SizeOf(_HandDataPackage);
  125.      end;
  126.      //向好友发送上线信息
  127.      UdpServer.SendBuffer(_tempIP,_tempPORT,_HandDataPackage,SizeOf(_HandDataPackage));
  128.      sleep(1);
  129.      //取回此好友信息
  130.      with _FriendDataPackage do
  131.      begin
  132.        Head.MsgType:=IntToStr(FriendDataSign);
  133.          StrPCopy(Body.Account,_tempUserBasicInfo.UserData.Account);
  134.          if i=0 then
  135.          begin
  136.             StrPCopy(Body.IsFirstOne,IsTrue);
  137.          end;
  138.          StrPCopy(Body.IP,_tempUserBasicInfo.UserData.IP);
  139.          StrPCopy(Body.PORT,_tempUserBasicInfo.UserData.PORT);
  140.       //Head.DataSize:=SizeOf( _FriendDataPackage);
  141.       UdpServer.SendBuffer(_PeerIP,_PeerPORT,_FriendDataPackage,SizeOf(_FriendDataPackage));
  142.       Sleep(1);
  143.      end;
  144.    end;
  145.    //注册自己的信息
  146.    _tempUserBasicInfo:=TServerUserBasicInfo.Create ;
  147.    StrPCopy(_tempUserBasicInfo.UserData.Account,_Account);
  148.    StrPCopy(_tempUserBasicInfo.UserData.IP,_PeerIP);
  149.    StrPCopy(_tempUserBasicInfo.UserData.PORT,IntToStr(_PeerPORT));
  150.    Onlineusers.AddObject(_Account,_tempUserBasicInfo);
  151.    Memo1.Lines.Add('用户:'+_Account+'['+_PeerIP+':'+IntToStr(_PeerPORT)+'登录上线!');
  152. end;
  153. //用户注销处理
  154. function TServer.ProcRecvLogoutData(ThisBinding:TIdSocketHandle;LogoutData:TLogoutData):boolean;
  155. var _Account,_tempIP,_PeerIP:string;
  156.     i,TheTag,_tempPort,_PeerPORT:Integer;
  157.     _tempUserBasicInfo:TServerUserBasicInfo;
  158.     LogoutDataPackage:TLogoutDataPackage;
  159. begin
  160.   _Account:=LogoutData.Account;
  161.   _PeerIP:=thisbinding.PeerIP ;
  162.   _PeerPORT:=thisbinding.PeerPort;
  163.   TheTag:=OnlineUsers.IndexOf(_Account);
  164.   if TheTag>=0 then
  165.   begin
  166.      //删除用户在线信息
  167.      OnlineUsers.Delete(TheTag);
  168.      Memo1.Lines.Add('用户:'+_Account+'['+_PeerIP+':'+IntToStr(_PeerPORT)+'注销下线!');
  169.      with LogoutDataPackage do
  170.      begin
  171.         Head.MsgType:=IntToStr(LogoutSign);
  172.           StrPCopy(Body.Account,_Account);
  173.           StrPCopy(Body.lResult,IsTrue);
  174.         //
  175.      end;
  176.      UdpServer.SendBuffer(_PeerIP,_PeerPORT,LogoutDataPackage,SizeOf(LogoutDataPackage));
  177.      {//向好友发送下线信号
  178.      for i:=0 to OnlineUsers.Count-1 do
  179.      begin
  180.         _tempUserBasicInfo:=TServerUserBasicInfo(Onlineusers.Objects[i]);
  181.         _tempIP:=_tempUserBasicInfo.UserData.IP;
  182.         _tempPORT:=StrToInt(_tempUserBasicInfo.UserData.PORT);
  183.         with LogoutDataPackage do
  184.         begin
  185.             Head.MsgType:=IntToStr(LogoutSign);
  186.               StrPCopy(Body.Account,_Account);
  187.             //
  188.         end;
  189.         UdpServer.SendBuffer(_tempIP,_tempPORT,LogoutDataPackage,SizeOf(LogoutDataPackage));
  190.      end;
  191.      }
  192.   end;
  193. end;
  194. //转发处理P2P请求
  195. function TServer.ProcRecvP2PData(ThisBinding:TIdSocketHandle;HandData:THandData):boolean;
  196. var toIP,toPort:string;
  197.     HandDataPackage:THandDataPackage;
  198. begin
  199.     toIP:=HandData.DesIP;
  200.     toPort:=HandData.DesPORT;
  201.     with HandDataPackage do
  202.     begin
  203.          Head.MsgType:=IntToStr(HandSign);
  204.            Body.Account:=HandData.Account;
  205.            Body.DesIP:=HandData.DesIP;
  206.            Body.DesPORT:=HandData.DesPORT;
  207.            Body.NeedReBack:=HandData.NeedReBack;
  208.          //Head.DataSize:=SizeOf(HandDataPackage);
  209.     end;
  210.     UdpServer.SendBuffer(toIP,StrToInt(toPort),HandDataPackage,SizeOf(HandDataPackage));
  211.     Sleep(1);
  212. end;
  213. end.