1

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()
4

1 に答える 1

1

私は大学にいるので、このコードを外部でまだテストしていませんが、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

私はそれを完全には理解していませんが、私にとってはうまくいきます。ここから 適応 した. 彼らが言っていることを理解するには、ページ全体を数回読む必要があります。「IP_MULTICAST_TTL」のページを検索してくださいsocket.IP_MULTICAST_TTL, 33。sock.setsockopt で設定する必要があることがわかりました。ここで、番号は 32 を超える任意の番号です。この段階では、あなたと同じくらい確信が持てないことを覚えておいてください...

于 2013-05-20T04:54:41.233 に答える