看了网上说的很多的原理:我也用Delphi写了一个测试程序。主要用到了Indy控件。使用的是Udp协议,现在我的测试是:服务端在有公网IP的电脑上运行,同时在公网上再运行一个客户端。然后再运行几个客户端,这几个客户端我分别分发给网友,让他们帮我测试。
   一、有些用户登录都登不上,而有些用户则能登上。对于不能登上的用户。PING公网IP都是通的,没有一个不是通的。但就是不知道为什么连不上。换了80端口也不行。
   二、对于登录上的用户。跟位于公网上的客户端C发送消息,都能发送成功,而且C跟其它网友发送,同样也能成功。
   三、让服务端位于公网IP上,而其它的客户端位于不同的NAT后,因为网友们都很忙,我晕,始终找不到两个都能登录上的人帮我测试下。所以没有测试。
   我在客户端只放了一个InUdpClient控件,其host为公网IP,port为5555。而服务端则只放了一个InUdpServer控件,只设置了它的端口为5555.处理过程:
   客户端A与B分别登录上服务端S后,会得到其它所用登录用户的信息(包括被NAT转换后的IP与PORT),我做的界面类似于QQ样的界面。这样就可以跟每一个用户发送消息了。
   我所认为的P2P原理:A想与B通信,首先A先向B发一个消息,这时肯定发不过去(同一局域网的除外),所以通过服务器S,A要S跟B发一个指令,要求B向A发一个包过去。先不管能否接收到。这几步之后,他们之间就可以互相通信了。不知道有没有错,忘指正^_^,其实我也是看了网上流传很广的那个C++写的程序。
   我的程序是在服务端用InUdpServer的OnRead函数来读收到的消息。并根据消息类型,采取不同的行动。代码类似如下:          《注意:我前面说的客户端与服务端的Indy控件的属性没有改变过》
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
begin
//根据Adata转换为自定义的数据结构,并分析出发过来的消息类型。
//根据消息类型,分别调用不同的函数进行处理。
//处理函数类似于这样的,请看:  
//IdUDPServer1.SendBuffer(UserInfo^.Host, UserInfo^.Port, Packet, SizeOf(Packet)); 
end;而在客户端我利用了InUdpClient的收与发的功能。我本想用InUdpServer来接收的,但不知道放这个后怎么设置就没有用这个。我在登录上后就开了一个线程。这个线程里面是这样的,有一个循环,不断的接收消息。但有时候没有消息时就报错,所以我放入了try中。过滤掉。有消息就再调用相应的处理函数。程序大概如下:
  while true
  if 登录成功 then
   就开一个线程来对接收到的消息进行判断,是什么,并做相应的处理
  else
    退出发送消息部分是这样的:(在聊天窗口中)
for i:= 0 to 2 do//三次循环,三次都发不过去就认为超时
begin
//首先发送消息P2PMsg,
//然后等待对方接收到消息后就发个消息,把标志Flag置位
  for j:=0 to 9 do
  begin
    if Flag = True then
      exit
    else
      sleep(200);
  end;
 //到这里了就是对方没有收到了,就向服务端发送请求,请对方向我打个洞。
end;
//三次都没有收到就显示超时。现在发现有两个问题:
一、对方如果本就可以收到,也收不到对方发过来的置标志位的包,我根本就不能把标志置位,所以一收就收三条信息。
二、如果对方本来就收不到,经我双方打洞后,还是收不到郁闷请有这方面精验的朋友帮下我
我不知道这些问题是怎么回事,是我打洞原理不对,还是我的INDY控件的用法不对?我看网上一个贴是用的两个InUdpServer.请大家帮帮忙。我快要疯了。

解决方案 »

  1.   

    1.打洞原理大致是这样的.
    2.建议这样处理:S有一个在线用户表(含IP:PORT),若有一个新的用户N登录上线,则向它的好友们发送上线通知,仿QQ那样,这个通知里包含N的(IP:PORT),好友们在收到N的上线信号后向它发送一个包(把门打开);N在取回所有好友(含IP:PORT)后再向它们发一个包,此时就应该通了.注意:S处理的先后,一定要让好友们先发;2.注意NAT会话的维系,(定时发包)
    3.建议C/S双方都使用IDUDPSERVER.
      

  2.   

    to 小星星:
    对于第二点。你说一定要在客户端都从服务端得到各自的(IP:Port)后。如果是A想与B通信,那就必须是B先与A发,然后A再与B发。这样对吗?
    对于第三点。你说两边都用InUdpServer,那在客户端的InUdpServer怎么设置呢。在线等待。
      

  3.   

    如果INDY控件还不行,我决定改用TUdpSocket的。小星星说话
      

  4.   

    1.第二点-->是这样的.反正一先一后.且之间的时间不要太长了.最好是小于分钟级的.
    2.第三点-->无需要特别的设置.按服务端那样侦听,只是作用不一样而也,当然代码也不一样...
    P.S. 可不可以加个请字呀:P
      

  5.   

    请问下小星星。你加我QQ说好不好?请加我QQ:39576450
      

  6.   

    大哥,不要吓唬我好不好,我以为牛人来了呢!
    p2p是对等网络,和你概念上的理解有很大出入!我还说呢,俺从大2就做jxta,现在做到大4,看了你的文章,这个寒啊~~~这就是您对P2P
      

  7.   

    gemouzhi(gemouzhi) 如果你有别的见解,请到另一个贴看看。也是我发的。查我的名字找下,就在后面几页中。