UDP 및 브로드 캐스트 메시지를 사용하여 서로 다른 응용 프로그램을 검색하려고합니다. 응용 프로그램은 주기적으로 자신이 누구이며 무엇을 할 수 있는지 나타내는 UDP 패킷을 보냅니다. 처음에는 INADDR_BROADCAST에 브로드 캐스트하는 용도로만 사용됩니다.UDP 패킷을 수신하면 SO_REUSEADDR을 사용할 때 127.0.0.1로 보냅니다.
모든 응용 프로그램은 수신 대기 포트 (따라서 SO_REUSEADDR)를 공유합니다. 이벤트 커널 객체가 소켓에 첨부되어 새로운 패킷을 가져 와서 WaitFor 루프에서 사용할 수있을 때 알림을받습니다. 소켓은 비동기로 사용됩니다.
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;
수신 패킷 : 지정한 주소 목록에 데이터를 전송
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);
:
소켓을 열면 우리가 사용하는 방송 데이터를 전송
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을 사용할 때 하나의 응용 프로그램에서만 패킷을 수신합니다.
setsocketopt를 사용하여 IPPROTO_IP, IP_MULTICAST_LOOP을 1로 설정해도 아무 것도 변경되지 않습니다.
브로드 캐스트 대신 멀티 캐스트를 살펴 보겠습니다. 귀하의 예제에서 볼 수있는 것은 IP_ADD_MEMBERSHIP/IP_MULTICAST_LOOP을 조사해야한다는 것입니다. 예제를 가져 주셔서 감사합니다. –
일을 시도한 후에 방송 대신 멀티 캐스팅을 사용했습니다. –