简体   繁体   English

扭曲不发送数据

[英]Twisted not sending data

server.py server.py

from twisted.python import log
from twisted.internet import reactor,ssl, protocol
import config
import uuid
import json
import header

class cl:
    clients = list()
    source = None
    sourceID = None
    sent_header = list()
    id3_headers = {
        "pyc-title": "None",
        "pyc-length": "0",
    }

class RadioServer(protocol.Protocol):

    def connectionMade(self):
        if config.PyCasterMaxListeners != len(cl.clients):
            self.id = str(uuid.uuid4())
            self.peer = str(self.transport.getPeer())
            self.transport.write(header.header)
            cl.clients.append(self)
            print("Client-Connected-IP: "+self.peer)
            print("Client-Connected-ID: " + self.id)
        else:
            self.transport.abortConnection()

    def connectionLost(self, reason):
        if self.id == cl.sourceID:
            print("Source-Closed: "+ str(reason))
            cl.sourceID = None
            cl.source = None
        else:
            self.removeClient(self.id)
            print("Client-Closed-Reason: " + reason)
            print("Client-Closed-IP: " + self.peer)
            print("Client-Closed-ID: " + self.id)

    def dataReceived(self, data):
        dct = json.loads(data, encoding="utf8")
        if dct.has_key("PyCasterAuth"):
            if not cl.sourceID:
                auth = dct['PyCasterAuth']
                if auth == config.PyCasterAuth:
                    cl.source = self
                    cl.sourceID = self.id
                    self.transport.write("ok")
                    print("Source-Registered")
                    print("Source-ID: " + self.id)
                else:
                    cl.source.transport.write("denied")
                    print("Source-Login-Denied-IP: " + self.peer)
                    print("Source-Login-Denied-ID: " + self.id)
            else:
                print("Source-Exists-IP: " + self.peer)
                print("Source-Exists-ID: " + self.id)
                self.closeCl(self.id)
        elif dct.has_key("buffer"):
            buffer = dct['buffer']
            self.sendClients(buffer, bin=True)

        elif dct.has_key("info"):
            cl.id3_headers = dct['info']

    def removeClient(self, id):
        for client in cl.clients:
            if client.id == id:
                cl.clients.remove(cl)
                if client in cl.sent_header:
                    cl.sent_header.remove(client)

    def closeCl(self, id):
        for client in cl.clients:
            if client.id == id:
                self.removeClient(id)
                client.transport.abortConnection()
                print("Server-Closed-Client: (%s, %s)" % (id, client.peer))

    def sendClients(self, msg, bin=False):
        for client in cl.clients:
            if bin:
                if client not in cl.sent_header:
                    head = header.header
                    for k, v in iter(cl.id3_headers.items()):
                        head += k + ":" + v
                    client.transport.write("HTTP/1.1 200 OK\r\n")
                    client.transport.write(head)
            client.transport.write(msg)
            if config.PyCasterSendLogging:
                print("SENT %i bytes TO %s" % (len(msg), client.id))


if __name__=="__main__":
    import sys
    key = config.PyCasterSSLKey
    cert = config.PyCasterSSLCert
    factory = protocol.Factory()
    log.startLogging(sys.stdout)
    factory.protocol = RadioServer
    if config.PyCasterSSL:
        reactor.listenSSL(config.PyCasterPort, factory,  ssl.DefaultOpenSSLContextFactory(key, cert))
        reactor.run()
    else:
        reactor.listenTCP(config.PyCasterPort, factory)
        reactor.run()

config.py config.py

PyCasterAuth = "123abc"
PyCasterPort = 4446
PyCasterSSL = False
PyCasterSSLKey = None
PyCasterSSLCert = None
PyCasterMaxListeners = 32
PyCasterSendLogging = True
PyCasterLogFile=open("pycaster.log", "w") #can be sys.stdout

header.py contains a variable of the header data to be sent header.py包含要发送的标头数据的变量

I provided the whole server so you can run and understand my issue. 我提供了整个服务器,因此您可以运行并了解我的问题。 After the auth gets sent if its correct the server sends ok but the issue is self.transport.write("ok") doesn't get seen by the client. 在发送身份验证后,如果正确,则服务器发送ok但问题是self.transport.write("ok")未被客户端看到。 I've tried googling but I got no fixes. 我曾尝试使用Google谷歌搜索,但没有解决方法。

So multiple issues with your approach. 您的方法有很多问题。 First of you all your inheriting the approach from an echo server and making your way out. 首先,您要从回显服务器继承该方法并做出选择。 And from the looks of it, it seems you need an HTTP Server. 从外观上看,您似乎需要一个HTTP Server。 So look at below for example of request and response 因此,请看下面的请求和响应示例

http://twistedmatrix.com/documents/current/web/howto/web-in-60/dynamic-content.html http://twistedmatrix.com/documents/current/web/howto/web-in-60/dynamic-content.html

Also if you need to understand issues with your code. 另外,如果您需要了解代码问题。 Then it is mainly your dataReceived. 那就主要是你的数据了。

def dataReceived(self, data):
    dct = json.loads(data, encoding="utf8")
    if dct.has_key("PyCasterAuth"):
        if not cl.sourceID:
            auth = dct['PyCasterAuth']
            if auth == config.PyCasterAuth:
                cl.source = self
                cl.sourceID = self.id
                self.transport.write("ok")
                print("Source-Registered")
                print("Source-ID: " + self.id)
            else:
                cl.source.transport.write("denied")
                print("Source-Login-Denied-IP: " + self.peer)
                print("Source-Login-Denied-ID: " + self.id)
        else:
            print("Source-Exists-IP: " + self.peer)
            print("Source-Exists-ID: " + self.id)
            self.closeCl(self.id)
    elif dct.has_key("buffer"):
        buffer = dct['buffer']
        self.sendClients(buffer, bin=True)

    elif dct.has_key("info"):
        cl.id3_headers = dct['info']

You are assuming data will have body. 您假设data将具有主体。 While that is not true, it will have the headers also. 虽然那不是真的,但它也将具有标头。 So your call will fail. 因此您的通话将失败。 A simple workaround you can add is below 您可以添加的简单解决方法如下

    data_body = data.split(b"\r\n\r\n")[1]
    dct = json.loads(data_body, encoding="utf8")

Next key checking should be done like this 下一步密钥检查应像这样完成

    if "PyCasterAuth" in dct:

as there is no method has_key . 因为没有方法has_key Also at the end of the dataReceived you want to close the request so it doesn't keep on waiting 同样在dataReceived的末尾,您想关闭请求,这样它就不会继续等待

self.transport.loseConnection()

So updated function is as below 所以更新的功能如下

def dataReceived(self, data):
    data_body = data.split(b"\r\n\r\n")[1]
    dct = json.loads(data_body, encoding="utf8")
    if "PyCasterAuth" in dct:
        if not cl.sourceID:
            auth = dct['PyCasterAuth']
            if auth == config.PyCasterAuth:
                cl.source = self
                cl.sourceID = self.id
                self.transport.write(b"ok")
                print("Source-Registered")
                print("Source-ID: " + self.id)
            else:
                cl.source.transport.write("denied")
                print("Source-Login-Denied-IP: " + self.peer)
                print("Source-Login-Denied-ID: " + self.id)
        else:
            print("Source-Exists-IP: " + self.peer)
            print("Source-Exists-ID: " + self.id)
            self.closeCl(self.id)
    elif dct.has_key("buffer"):
        buffer = dct['buffer']
        self.sendClients(buffer, bin=True)

    elif dct.has_key("info"):
        cl.id3_headers = dct['info']

    self.transport.loseConnection()

But as I mentioned you should not be using this approach rather one from the link I added. 但是正如我提到的,您不应使用这种方法,而应使用我添加的链接中的一种方法。

Below is a simple test 下面是一个简单的测试

 curl -v -H "Content-Type: application/json" -X POST -d '{"PyCasterAuth":"123abc"}' localhost:4446
Note: Unnecessary use of -X or --request, POST is already inferred.
* Rebuilt URL to: localhost:4446/
*   Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 4446 failed: Connection refused
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 4446 (#0)
> POST / HTTP/1.1
> Host: localhost:4446
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 25
>
* upload completely sent off: 25 out of 25 bytes
Name: Tarun
* Connection #0 to host localhost left intact
ok%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM