質問

UDPとブロードキャストメッセージを使用して、一連のアプリケーションにお互いを発見しようとしています。アプリケーションは、定期的にUDPパケットを送信し、自分が誰であり、何ができるかを示します。最初は、inaddr_broadcastにブロードキャストするためにのみ使用します。

すべてのアプリケーションは同じポートを共有してリッスンします(したがってSO_REUSEADDR)。イベントカーネルオブジェクトがソケットに接続されているため、新しいパケットを取得してWaitFor Loopで使用できるときに通知が表示されます。ソケットは非同期に使用されます。

ソケットを開く:

FBroadcastSocket := socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if FBroadcastSocket = INVALID_SOCKET then Exit;
i := 1;
setsockopt( FBroadcastSocket, SOL_SOCKET, SO_REUSEADDR, Pointer( @i ), sizeof( i ) );
i := 1;
setsockopt( FBroadcastSocket, SOL_SOCKET, SO_BROADCAST, Pointer( @i ), sizeof( i ) );
System.FillChar( A, sizeof( A ), 0 );
A.sin_family      := AF_INET;
A.sin_port        := htons( FBroadcastPort );
A.sin_addr.S_addr := INADDR_ANY;
if bind( FBroadcastSocket, A, sizeof( A ) ) = SOCKET_ERROR then begin
    CloseBroadcastSocket();
    Exit;
end;
WSAEventSelect( FBroadcastSocket, FBroadcastEvent, FD_READ );

指定されたアドレスのリストにデータを送信します。

for i := 0 to High( FBroadcastAddr ) do begin
    if sendto( FBroadcastSocket, FBroadcastData[ 0 ], Length( FBroadcastData ), 0, FBroadcastAddr[ i ], sizeof( FBroadcastAddr[ i ] ) ) < 0 then begin
        TLogging.Error( C_S505, [ GetWSAError() ] );
    end;
end;

受信パケット:

procedure TSocketHandler.DoRecieveBroadcast();
var
    RemoteAddr:    TSockAddrIn;
    i, N:          Integer;
    NetworkEvents: WSANETWORKEVENTS;
    Buffer:        TByteDynArray;
begin
    // Sanity check.
    FillChar( NetworkEvents, sizeof( NetworkEvents ), 0 );
    WSAEnumNetworkEvents( FBroadcastSocket, 0, @NetworkEvents );
    if NetworkEvents.ErrorCode[ FD_READ_BIT ] <> 0 then Exit;

    // Recieve the broadcast buffer
    i := sizeof( RemoteAddr );
    SetLength( Buffer, MaxUDPBufferSize );
    N := recvfrom( FBroadcastSocket, Buffer[ 0 ], Length( Buffer ), 0, RemoteAddr, i );
    if N <= 0 then begin
        N := WSAGetLastError();
        if N = WSAEWOULDBLOCK then Exit;
        if N = WSAEINTR then Exit;
        TLogging.Error( C_S504, [ GetWSAError() ] );
        Exit;
    end;

    DoProcessBroadcastBuffer( Buffer, N, inet_ntoa( RemoteAddr.sin_addr ) );
end;

inaddr_broadcast、ローカルブロードキャストアドレス(192.168.1.255)またはローカルIPアドレスを使用して放送データを送信すると、すべてが正常に機能します。 127.0.0.1を使用して「ブロードキャスト」する瞬間、受信は散発的ですが、一般的には機能しません。

誰かがこれを解決する方法を持っていますか(アドレスリストは変更可能です)?他のすべてが失敗した場合、すべてのローカルIPアドレスを検索し、127.0.0.1をそれに置き換えますが、IPアドレスが変更されると問題が発生します。

更新:APP1を最初に開始すると、App1はパケットを受信します。次に、app2を開始します。これで、App1はパケットを受け取りますが、App2は受け取りません。 App1を停止すると、App2はパケットの受信を開始します。 App3を起動すると、App2はパケットを受信しますが、App3は受信しません。

したがって、127.0.0.1を使用すると、パケットを受信するアプリケーションは1つだけです。

また、IPPROTO_IP、IP_MULTICAST_LOOPをSetSocketoPTで1に設定しても、何も変更されません。

役に立ちましたか?

解決

コードを使って試してみたばかりでXMLタグが表示されます。表示するメモ帳でそれを開けてみてください。

あなたのforeachループはあなたの文字列を連結する必要があります。

outtext .= '<property><postcode> $arow["pCode"] </postcode> 
<price> $arow["price"]</price> <imagefile> $arow["iFile"] </imagefile> <visits> 
$arow["visits"]  
</visits>    </property> \n'; 
.

foreachの場合、sqlite_fetch_allが配列を返すことです。あなたはそれを変数として扱っています。

foreach ($result as $oneproperty)を使用してみてください。データベースがどのように構造化されているかわからないので、それがあなたのために機能しない場合、$resultを使用してvar_dump($result)の出力を投稿してください。

上記は、リテラル文字列が出力され、変数が挿入されないことを意味します。あなたはこれをする必要があります:

outtext .= '<property><postcode>'. $arow["pCode"]. '</postcode> 
<price>'. $arow["price"].'</price> <imagefile>'. $arow["iFile"].' </imagefile> <visits>'. 
$arow["visits"].'
</visits>    </property> \n'; 
.

最後に、文字列を手動で手動で作成する代わりに、 XML Writer

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top