0

現在私はC++言語を知っている私のチームの唯一の人です。したがって、私は既存の(着用可能な)Webアプリケーション用のネイティブtizenサービスを作成するタスクを担当しました。TizenエミュレータUDP接続

サービスの主な目的は、同じネットワーク内のシステムからブロードキャストされている(つまり同じアクセスポイントに接続されている)UDPメッセージを受信することです。

私は2つのシンプルなpythonスクリプトを作った。一つ目は、ボタンのクリックにブロードキャストメッセージを送信します。

class UDPServer(object): 
    ''' 
     A simple UDP server with a send method. 
    ''' 

    def __init__(self): 
     ''' 
      Initializes the server. 
     ''' 
     import socket 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
     self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) 

    def broadcast_message(self, message): 
     ''' 
      Sends out a broadcast message. 
     ''' 
     self.socket.sendto(message, ('<broadcast>', 3333)) 


class GUI(object): 
    ''' 
     A simple UI to use the server with. 
    ''' 

    def __init__(self): 
     ''' 
      Initializes the simple ui. 
     ''' 
     import Tkinter 
     self.root = Tkinter.Tk() 
     self.root.title("UDP System") 
     self.button = Tkinter.Button(self.root, text="Action!") 
     self.button.place(x=0, y=0) 
     self.button.pack(fill='x') 
     self.root.update() 

    def action(self, callback, *args): 
     ''' 
      Sets the action to be performed when the button's being called. 
     ''' 
     self.button.configure(command=lambda: callback(*args)) 

    def run(self): 
     ''' 
      Invokes the message pump of the root widget. 
     ''' 
     self.root.mainloop() 

def main(): 
    ''' 
     Launches the UDP server and its ui. 
    ''' 
    server = UDPServer() 
    gui = GUI() 
    gui.action(server.broadcast_message, "Hello, World!") 
    gui.run() 


if __name__ == '__main__': 
    main() 

、後者はそれらのメッセージを受信します。私は他によって発行されたメッセージを受信できていますので、

class GUI(object): 
    ''' 
     Simple GUI for the receiver. 
    ''' 

    def __init__(self): 
     ''' 
      Initializes the UI. 
     ''' 
     import Tkinter 
     self.root = Tkinter.Tk() 
     self.root.title("UDPReceiver") 
     self.list = Tkinter.Listbox(self.root) 
     self.list.pack(fill='x') 

    def add_message(self, message): 
     ''' 
      Adds an message to the listbox. 
     ''' 
     self.list.insert(0, message) 

    def run(self): 
     ''' 
      Runs the widgets mainloop. 
     ''' 

     self.root.mainloop() 

class Receiver(object): 
    ''' 
     Simple UDP receiver. 
    ''' 

    def __init__(self): 
     ''' 
      Initializes a simple udp receiver/client. 
     ''' 
     import socket 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
     self.socket.bind(('', 3333)) 

    def recv(self): 
     ''' 
      Listens for a message and returns it. 
     ''' 
     return self.socket.recvfrom(4096) 

def main(): 
    ''' 
     Launches the udp receiver and its ui. 
    ''' 
    gui = GUI() 
    client = Receiver() 

    def proc(): 
     ''' 
      A simple fetch and update routine to be run 
      in a seperate thread. 
     ''' 
     while gui.root.state() == 'normal': 
      msg = client.recv() 
      gui.add_message(msg) 

    from thread import start_new_thread 
    start_new_thread(proc,()) 
    gui.run() 

if __name__ == '__main__': 
    main() 

どうやら両方のスクリプトは、正しく動作していますスクリプト(しかし、同じPC上でのみテストしました)

私はネイティブサービスの "リスニング動作"を実装しようとしています。アプリケーションはクラッシュすることなく正常に動作するようです。 -

UDPSocket::UDPSocket() 
: socket{0} 
{ 
    addrinfo hints{0, }; 
    const char*  pHostname = 0; 
    const char*  pPortname = "3333"; 
    hints.ai_family  = AF_UNSPEC; 
    hints.ai_family  = SOCK_DGRAM; 
    hints.ai_protocol = 0; 
    hints.ai_flags  = AI_PASSIVE | AI_ADDRCONFIG; 

    addrinfo* res{nullptr}; 
    int err = ::getaddrinfo(pHostname, pPortname, &hints, &res); 
    if(0 != err){ 
     throw std::runtime_error{"Failed to get address info."}; 
    } 

    socket = ::socket(res->ai_family, res->ai_socktype, res->ai_protocol); 
    if(-1 == socket){ 
     throw std::runtime_error{"Failed to create socket."}; 
    } 

    int broadcast = 1; 
    ::setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); 

    err = ::bind(socket, res->ai_addr, res->ai_addrlen); 
    if(-1 == err){ 
     throw std::runtime_error{"Failed to bind socket."}; 
    } 

    freeaddrinfo(res); 
} 

UDPSocket::~UDPSocket() 
{ 
    close(socket); 
} 

std::string  UDPSocket::listen() const{ 


    char    buffer[512]; 
    sockaddr_storage src_addr; 
    socklen_t   src_addr_len = sizeof(src_addr); 
    ssize_t    count = ::recvfrom(socket, 
              buffer, 
              sizeof(buffer), 
              0, 
              (sockaddr*) &src_addr, 
              &src_addr_len); 

    if(-1 == count){ 
     throw std::runtime_error{strerror(errno)}; 
    } else if (count == sizeof(buffer)){ 
     // Issue warning 
     return buffer; 
    } else{ 
     return buffer; 
    } 
} 

アプリケーションは「UDPSocket ::聞くの()」を呼び出すときに、サービスの屋台という事実を除いて、エミュレータで罰金を実行している:コードを以下を罰金だが、しかしそれは、何も受信しません私はそれが私がブロッキングモードにあるという事実によると思います。送信ボタンを押す頻度に関係なく、私のローカルネットワークにUDPメッセージを氾濫させることはありません。

TL; DR TizenエミュレータでUDPメッセージを受信するために特別な設定手順が必要ですか?

ボーナス質問: 受信UDPメッセージを継続的に監視する方法が必要です。 サービス内の「受信者」の追加スレッドを開始する必要がありますか?

答えて

0

[OK]をクリックして問題を解決しました。

hints.ai_socktype = SOCK_DGRAM; 

代わりの

hints.ai_family = SOCK_DGRAM; 

私は忘れてしまった第二のミスやより良いもの: ポート転送を確立 最初の間違いは、自動補完間違いでした。

将来の読者の場合: ポート転送を確立するとき(エミュレータ>設定>ネットワークを右クリック)、ポートは空き状態になっている必要があります。別のアプリケーションがすでにこのポートにバインドされているソケットを持っている場合は、エラーメッセージが表示されます。

関連する問題