2013-05-20 83 views
1

我想創建一個聊天程序,它可以通過UDP穿孔工作並直接連接到由代理提供的節點。UDP穿孔不工作

我現在擁有的腳本在本地工作得很好。當我嘗試使用外部地址連接時出現問題。我無法親自理解這一點,所以我希望有人能幫助我!

import socket 
import json 
import landerdb 
import threading 

class PeerChat: 

    address = None 

    def __init__(self): 
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
     self.db = landerdb.Connect("nodes") 
     self.brok_ip = "" 
     self.brok_port = 5000 
     self.nick = "Test" 
     self.friends = [] 

    def listen(self): 
     self.command = { 

      "HERE":self.here, 
      "MSG":self.msg, 
      } 

     global address 
     self.sock.bind(address) 
     while True: 
      msg, addr = self.sock.recvfrom(1024) 
      try: 
       data = json.loads(msg) 
      except: 
       continue 
      if data[u'cmd'] in self.command: 
       threading.Thread(target=self.command[data[u'cmd']], args=(addr, data)).start() 

    def main(self): 
     while True: 
      msg = raw_input("> ") 
      msg = msg.split() 
      try: 
       msg = json.dumps({"cmd":msg[0], "data":' '.join(msg[2:]), "nick":self.nick, "to":msg[1]}) 
      except: 
       continue 
      for x in self.db.find("nodes", "all"): 
       self.sock.sendto(msg, tuple(x['addr'])) 

    def here(self, addr, data): 
     if not self.db.find("nodes", {"addr":addr}): 
      self.db.insert("nodes", {"addr":addr}) 
     if data['nick'] in self.friends: 
      print data['nick'] + " has come online." 
    def msg(self, addr, data): 
     if data['to'] == self.nick: 
      print data['nick']+": "+data['data'] 

    def GetNodes(self): 
     self.sock.sendto("", (self.brok_ip, self.brok_port)) 
     with open("nodes", 'wb') as file: 
      while True: 
       msg, addr = self.sock.recvfrom(1024) 
       if msg == "\n": 
        break 
       file.write(msg) 
     msg, addr = self.sock.recvfrom(1024) 
     global address 
     address = ("0.0.0.0", int(msg)) 
     for x in self.db.find("nodes", "all"): 
      addr = tuple(x['addr']) 
      self.sock.sendto(json.dumps({"cmd":"HERE", "nick":self.nick}),addr) 

if __name__ == "__main__": 
    PeerChat().GetNodes() 
    threading.Thread(target=PeerChat().listen).start() 
    PeerChat().main() 
+0

'全球地址'似乎不對,但我不知道,這是否是原因。 'address'不是全局變量,它只是一個類變量。你應該刪除這一行。 – Hendrik

回答

1

我還沒有在外部測試過這個代碼,因爲我在uni,但我使用稍微不同的行來設置UDP連接。

他們可能給你一些想法...

#!/usr/bin/python 
import socket 
import struct 

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
sock.bind(('239.255.60.60', 4876)) 
mreq = struct.pack("=4sl", socket.inet_aton("239.255.60.60"), socket.INADDR_ANY) 
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 
packet_number = 0 

while True: 

    packet_number += 1 
    print packet_number 
    raw_data = sock.recv(1024) 
    print raw_data 
    print 

我不完全瞭解這一切,但它爲我工作。 它改編自here。你應該閱讀整個頁面幾次,以瞭解他們在說什麼。搜索'IP_MULTICAST_TTL'的頁面我收集到,您需要在sock.setsockopt中設置socket.IP_MULTICAST_TTL, 33,其中數字是任意數字> 32.請記住,我幾乎與您在此階段一樣不確定...