2014-05-24 10 views
1

저는 Twisted를 사용하여 파이썬에서 피어 투 피어 애플리케이션을 만들고 있습니다. 그것은 내 VPS 사이에 잘 ​​작동하지만 내 고향 기계에 연결하려고하면 작동하지 않습니다. NAT 또는 방화벽에서 방화벽과 관련이 있다고 가정합니다. 내 질문은, 누군가가 라우터 방화벽을 우회하는 방법 또는 트위스트와 NAT 뒤에있는 컴퓨터에 연결하는 방법을 알고 있습니까? 여기에 내 코드입니다 :Python Twisted bypass NAT

from twisted.internet import reactor, protocol 
from twisted.protocols import basic 
from sys import * 
import os.path 

if (argv[1] == ""): 
    HOST = "localhost" 
else: 
    HOST = argv[1] 

PORT = 9001 
if (os.path.isfile("zones/root.txt")): 
    root = open("zones/root.txt", "rw").read() 
else: 
    root = "" 

root1 = root 
root2 = "" 

maxPeers = 8 
peerCount = 0 
routingTable = [] 
ipaddress = [] 
depth = 0 
ip = "" 
peerId = "" 

class p2pClient(basic.LineReceiver): 

    global root 
    global root2 
    global checkRoot 
    global depth 

    clientTable = [] 

    def checkRoot(root2): 

     if (root1 == root2): 
     print "Roots are the same" 
     else: 
     print "Different roots." 

    def connectionMade(self): 
     print "connected to peer!" 

    def connectionLost(self, reason): 

     print "Disconnected from server!" 

    def lineReceived(self, data): 
     data = data.split("{}") 
     clientTable = data[0].replace("[","").replace("]","").replace("'","").replace(" ","").split(",") 
     root2 = data[1] 
     checkRoot(root2) 

class p2pClientFactory(protocol.ClientFactory): 
    protocol = p2pClient 

class p2pServer(basic.LineReceiver): 

    global routingTable 
    global addToRoutingTable 
    global removeFromRoutingTable 
    global ipaddress 

    def replace(l, X, Y): 
     for i,v in enumerate(l): 
      if v == X: 
       l.pop(i) 
       l.insert(i, Y) 

    def removeFromRoutingTable(ip): 
     routingTable.remove(ip) 

    def addToRoutingTable(ip): 

     routingTable.append(ip) 

    def sendData(self, msg): 

     self.transport.write("%s\r\n" % msg) 

    def connectionMade(self): 

     global peerCount # global allows us to use peerCount in our class 
     global depth 
     peerCount = peerCount + 1 # Update the peer count 

     #ip = self.transport.getHost().host 
     ip = self.transport.getPeer() 
     ip = str(ip) 
     ip = ip.split("'") 
     ip = ip[1] 
     ipaddress.append(ip) 

     addToRoutingTable(ip) 

     self.transport.write(str(routingTable) + "{}") 

     self.sendData(root) # Send the root zone file to peer 1 

     print "Peer Count : [ " + str(peerCount) + "/8 ]" 
     print "Routing Table: " + str(routingTable) 

    def connectionLost(self, reason): 

     global peerCount 

     peerCount = peerCount - 1 
     ipaddr = str(self.transport.getPeer()).split("'") 

     removeFromRoutingTable(ipaddr[1]) 

     print "Client Disconnected!" 
     print "Peer Count : [ " + str(peerCount) + "/8 ]" 
     print "Routing Table : " + str(routingTable) 

class p2pServerFactory(protocol.Factory): 

    protocol = p2pServer 

sfactory = p2pServerFactory() 
reactor.listenTCP(PORT, sfactory) 

cfactory = p2pClientFactory() 
reactor.connectTCP(HOST, PORT, cfactory) 

reactor.run() 

나는 코드가 긴 감사하지만 난 정말 어떤 도움을 감사하겠습니다. 감사!

답변

1

당신이 꼬인 코드를 사용하고 있다는 사실은 당신이 코드를 작성한 것과는 관련이 없습니다. 라우터에 NAT를 설정하여 포트 9001을 로컬 시스템의 IP로 전달해야합니다. 구성을 만드는 방법은 라우터에 따라 다릅니다. "NAT port forwarding + routername"을 검색하십시오. 나는 그것이 좋은 출발점이라고 생각한다. 드문 경우지만 일 수 있습니다.은 방화벽 문제 일 수 있지만 NAT 문제 일 가능성이 훨씬 큽니다.

+0

내 파이썬 프로그램을 이렇게 할 수 있습니까? 귀하의 답변 주셔서 감사합니다! – Francis

+2

이론상 예. 라우터에서 지원하는 경우 UPnP를 사용하여 코드 문제를 해결할 수 있습니다. 그러나 그것은별로 중요하지 않습니다. 숙련 된 네트워크/트위스트 프로그래머가 아니라면 내 생각에 실패 할 것입니다. ( 구현은 여기에서 가능합니다. https://github.com/fuzeman/PyUPnP 하지만 라우터를 구성하는 것이 좋습니다. 장치에 대한 Nat 규칙과 정적 DHCP 규칙을 작성하면 유용합니다. – brunsgaard

1

Twisted를 사용하여 피어 투 피어 응용 프로그램을 작성하려는 경우 Vertex은 UDP를 통한 스트림 기반 연결을 설정하기 위해 일부 NAT 통과 논리를 구현합니다. 불행히도 그 문서는 꽤 가늘며, 사용법을 정확히 기술하는 것은 너무 오랫동안 SO 답을 얻었지만 사용하려고 시도하고 버그를 작성하면 프로젝트의 일부 활동에 동기를 부여 할 수 있습니다.