나는 간단한 UDP 메시징 시스템에서 작업하고 있으며 대부분 작동하고 있습니다. 이 구조는 특정 포트에서 수신 대기하는 모든 클라이언트에게 메시지를 브로드 캐스트하는 서버 1 대를 가지고 있습니다 (LAN에 연결하거나 인터넷에 연결되지 않은 Ad-Hoc 네트워크에 연결하기 위해 테스트 용 PC가 현재 웹에 연결되어 있음). 내 문제는 내가 메시지를 보낼 때마다 클라이언트가 2 부를 받는다는 것이다. 현재 대상 IP를 서브넷으로 설정하지 않으므로 이것이 문제 일 수 있습니다.하나의 수신에 대해 여러 수신 메시지 받기
(참고 : "클라이언트"가 바인딩되어 있기 때문에 표준 클라이언트 - 서버 용어를 위반합니다. 특정 항구,하지만 나와 함께 곰). 포트는 클라이언트가 반복적으로 읽어 스레드를 생성합니다 연 후
d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
//Set port so that calls to recvfrom do not block. Instead recvfrom returns an error if no data is present now.
u_long l_no_block_specifier = 1;
int l_socket_control_result = ioctlsocket(d_socket,
FIONBIO,
&l_no_block_specifier);
if(d_socket == -1)
{
printf("\nError in creating socket");
return false;
}
//Zero out the broadcast address member to initialize it
memset(&d_server_address,
0,
sizeof(d_server_address));
//Specify that
d_server_address.sin_family = AF_INET;
d_server_address.sin_port = htons(34444);
d_server_address.sin_addr.s_addr = INADDR_ANY;
d_address_length = sizeof(d_server_address);
//Bind socket and print an error if bind fails.
if (bind(d_socket, (SOCKADDR*)&d_server_address, sizeof(SOCKADDR_IN)) != 0)
{
printf("\nError in binding socket");
}
:
d_socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(d_socket == -1)
{
printf("\nError in creating socket");
return false;
}
//socket option set to 1 because we are setting the SO_BROADCAST setting to true
//MSDN says to use int for boolean option types.
int l_socket_option = 1;
setsockopt(d_socket,
SOL_SOCKET,
SO_BROADCAST,
(char*)&l_socket_option,
sizeof(int));
//Zero out the broadcast address member to initialize it
memset(&d_broadcast_address,
0,
sizeof(d_broadcast_address));
//Specify that
d_broadcast_address.sin_family = AF_INET;
d_broadcast_address.sin_port = htons(34444);
d_broadcast_address.sin_addr.s_addr = INADDR_BROADCAST;
내 클라이언트가 포트과 같이 열립니다 : 그래서 여기
내 서버가 대상 데이터를 지정하는 방법입니다 항구. 필자는 메시지의 순서를 나타내는 모든 정수를 전송하는 작은 테스트 응용 프로그램을 작성했습니다. 이 프로그램의 출력은 다음과 같습니다 : 나는 꽤 그것을 철저하게 테스트 (프로그램 자체가 실수 각 메시지에 대해이 통지를 인쇄되지 않는다는 것을 확신했습니다
Sending message #0 at time = 4.0 Got message #0 at time = 4.0 Got message #0 at time = 25.0 Sending message #1 at time = 1004.0 Got message #1 at time = 1004.0 Got message #1 at time = 1047.0 Got message #2 at time = 2004.0 Sending message #2 at time = 2004.0 Got message #2 at time = 2064.0 Sending message #3 at time = 3005.0 Got message #3 at time = 3005.0 Got message #3 at time = 3086.0
타임 스탬프 쇼 외에 2 개의 영수증 사이의 뒤늦은 도착).
왜 이런 일이 발생합니까? 내 테스트 PC가 인터넷에 연결되어있어 브로드 캐스트 때문에 메시지가 내 자신의 PC로 되돌아 오는 2 개의 다른 경로를 통해 라우팅되기 때문에 이것이 원인이라고 추측합니다.
는 편집 :이 INADDR_ANY를 지정하는 대신 자신의 IP 주소를 사용하여 방송 포트를 결합하여이 중복 영수증을 중지하도록
나는 클라이언트를 변경했습니다. 또한 서버가 부분적으로 서브넷에서만 브로드 캐스팅되도록 업데이트했지만 여러 수신 확인에 영향을 미쳤다고 생각하지 않습니다.
당신은 실제 송신 또는 읽기 코드를 보여주지 않았지만, 특정 서브넷 브로드 캐스트 주소 대신에 'INADDR_BROADCAST' (255.255.255.255)로 보내고 있기 때문에 수신기를 INADDR_ANY '(0.0.0.0)을 사용하는 경우 수신기의 다른 NIC에서 각 메시지의 복사본을 여러 번받을 가능성이 있습니다. 각 NIC를 실제로 수신하는 NIC를 결정하려면'recvfrom() '대신 ['WSARecvMsg()'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms741687.aspx)를 사용할 수 있습니다 패킷. –
그래, 내가 보낸/받기 코드를 붙여 넣지 않았어. 내가 ipconfig를 할 때 "이더넷 어댑터 로컬 영역 연결"에서 2 개의 IP 주소와 "무선 LAN 어댑터 무선 네트워크 연결"에서 하나를 볼 수 있습니다. 그래서 나는 여분의 메시지가 메시지에 대한 내 컴퓨터에 2 개의 IP 대상을 가지고 있다는 사실에서 비롯된 것이라고 생각합니다. – Ian