네트워킹에서 바이트 순서를 안전하게 무시할 수 있습니까?


24

클라이언트가 Windows에서 실행되고 서버는 Linux에서 실행되는 서버 클라이언트 응용 프로그램을 개발 중입니다. 나중에 클라이언트를 Mac과 Linux로 이식 할 수도 있지만 아직은 아닙니다.

요즘 모든 가정용 컴퓨터는 리틀 엔디안에서 실행됩니다. 나는 잠시 동안 구글 검색을했지만 실제로 빅 엔디안에서 실행되는 장치 목록을 찾을 수 없었습니다. 내가 아는 한 일부 모토로라 칩은 여전히 ​​빅 엔디안과 일부 전화를 사용합니다 (앱을 스마트 폰으로 이식 할 계획이 없으므로 이것이 중요하지 않습니다). 그럼, 왜 I가, 이렇게 두 번 모든 정수, 모든 짧은, 모든 플로트의 바이트를 재 배열, 그리고 것 읽기 쓰기 이미 때, 알고 그 작은 엔디안에 모두 서버와 클라이언트 실행?

그것은 불필요한 일입니다. 내 질문은 : 엔디안을 안전하게 무시하고 리틀 엔디안 데이터를 보낼 수 있습니까? 단점은 무엇입니까?


4
머신이 일반적인 / 표준 빅 엔디안 데이터 대신 리틀 엔디안 데이터를 수신하고 있는지 어떻게 알 수 있습니까?
Ixrec

2
네트워크 프로토콜에 필요한 메타 데이터와 코드를 제외한 모든 사람이 해석 할 수없는 바이트 인 페이로드를 구별해야합니다. 나는 당신이 당신 자신의 네트워킹 스택을 굴리지 않기를 바랍니다. 결과적으로 질문은 페이로드에 관한 것입니다. 맞습니까?

2
@delnan 예, 페이로드에 대해서만 이야기하십시오. 물론 네트워크 스택 순서대로 네트워크 바이트 순서로 이야기 할 것입니다 .
tkausl

3
엔디안이 중요한 추상화 수준에서 작업해야합니까? 이 모든 하위 레벨 "메시"를 캡슐화하는 적절한 라이브러리가 존재하는 프로토콜을 사용하는 것이 좋습니다. 그런 다음 고객을 추가하면 훨씬 쉽게 추가 보너스를받을 수 있습니다.
godfatherofpolka

1
@tkausl 두 가지 측면 만 더 생각해보십시오. 일반적으로 IO는 계산에 비해 매우 느리므로 더 높은 추상화 수준에서 작업함으로써 발생하는 오버 헤드는 거의 무시할 수 있습니다. 영리한 리소스 풀링 및 비동기 처리 등으로 인해 일부 라이브러리가 수동 구현보다 성능이 우수 할 수도 있습니다. 따라서 먼저 기존 솔루션을 신중하게 평가합니다. 또한 설명을 고려할 때 성능보다는 확장성에 대해 몇 가지 생각을 할 것입니다. 여기서 더 높은 수준의 프로토콜을 사용하면 이점을 얻을 수 있습니다.
godfatherofpolka

답변:


29

... 서버와 클라이언트가 리틀 엔디안에서 실행된다는 것을 이미 알고있을 때 바이트를 다시 정렬하는 이유는 무엇입니까? 그것은 불필요한 일입니다.

코드가 리틀 엔디안 아키텍처에서 항상 실행되도록 보장 할 수있는 경우에만 불필요합니다. 오래 살기를 원한다면 빅 엔디안 아키텍처가 "in"한 것이되어서 좋은 시장이 될 때부터 10 년 동안 입증 된 코드를 방해하지 않는 추가 노력을 기울일 가치가 있습니다. 너의 어플리케이션.

네트워크 표준 바이트 순서가 있습니다. 빅 엔디안이지만 프로토콜을 설계 할 때 준수해야한다고 말하는 것은 없습니다. 코드를 실행하는 대부분의 시스템이 리틀 엔디안이고 성능이 중요하다는 것을 미리 알고 있다면 "tkausl 표준 바이트 순서"를 선언하고 함께 진행하십시오. 일반적으로 htons()필요한 순서대로 물건을 넣으라고 부르는 곳 htots()에서는 리틀 엔디안 아키텍처에서 조건부로 컴파일하지 않고 빅 엔디안에서 다시 정렬 하는 매크로를 작성하십시오 .

인바운드 및 아웃 바운드 변환을 수행하기위한 코드를 유지 관리하는 것은 실제로 큰 노력이 아닙니다. 매우 많은 수의 메시지가있는 경우 메시지를 표현하고 인바운드 및 아웃 바운드 변환을 생성하는 프로그램을 작성하는 방법을 찾으십시오.


10
문구는 when designing your protocol그것은 또한 암시 적으로 일부 기존 프로토콜을 구현할 때 새로운 프로토콜을 설계하지 않을 경우이 옵션은 존재한다는 것을 말한다 있기 때문에 중요하다. 그리고 htots(그리고 실제로 전체 기능 군) 의 필요성을 언급하면서 다른 바이트 순서를 선택하는 것이 코드를 간단하게 만드는 것이 아니라 약간 더 빠를 수도 있음을 분명히합니다.
kasperd

4
(비표준하지만 매우 일반적인 요즘) 기능이있다 htole32(), htole16(), le16toh()물론 가능 등 기능. 이러한 선언을 얻는 데 포함시킬 파일은 불행히도 표준이 적 <endian.h>거나 <sys/types.h>플랫폼에 따라 다릅니다.
torek

이 답변은 괜찮지 만, 주어진 사례가 사실보다 미신에 근거하여 틀린 가정 일 가능성이 높다고 가정 할 수 있습니다.
Doc Brown

1
@DocBrown : 저는 항상 X 프로토콜이 30 년 동안 자신의 바이트 순서를 고르는 것을 지원했으며, 그 당시에는 리소스가 부족한만큼 아무도 문제가되지 않았다고 불평하지 않았습니다.
Blrfl

7

당신의 프로토콜입니다.

안전하게 무시할 수 없습니다. 그러나 안전하게 라벨을 붙일 수 있습니다. 클라이언트와 서버를 제어합니다. 프로토콜을 제어합니다. 양측이 동의하는지 아는 한 빅 엔디안인지 리틀 엔디안인지 신경 쓰지 않는 것이 합리적이지 않습니까?

이것은 오버 헤드를 의미합니다. 이제 어떻게 든 엔디안을 표시해야합니다. 그렇게하면 무엇이든 읽을 수 있습니다.

데이터 오버 헤드를 원하지 않고 CPU가 지루하고 할 일을 찾고 있다면을 준수하십시오 .


6

내 질문은 : 엔디안을 안전하게 무시하고 리틀 엔디안 데이터를 보낼 수 있습니까?

이에 대한 두 가지 해석이 있습니다.

  • 당신은 항상 당신의 응용 프로그램 / 프로토콜을 설계 할 경우 1 개 송신 리틀 엔디안, 당신은 엔디안을 무시하지 않습니다.

  • 기본 엔디안이 무엇이든 보내거나 받도록 애플리케이션 / 프로토콜을 설계하면 동일한 기본 엔디안이있는 플랫폼에서 애플리케이션을 실행하는 한 작동합니다.

    "안전" 2 입니까? 그것은 당신이 판단하는 것입니다! 그러나 리틀 엔디안, 빅 엔디안 또는 ... 바이 엔디안을 사용하는 일반적인 하드웨어 플랫폼이 있습니다.

    참고:

단점은 무엇입니까?

엔디안을 무시하는 명백한 단점은 사용자 / 사용자가 서로 다른 네이티브 엔디안을 가진 플랫폼간에 응용 프로그램 / 프로토콜을 실행해야하는 경우 문제가 있다는 것입니다. 응용 프로그램이 중단되고 문제를 해결하기 위해 응용 프로그램을 변경해야합니다. 그리고 버전 호환성 문제 등을 다루십시오.

분명히, 대부분의 최신 세대 플랫폼은 기본적으로 리틀 엔디안이지만 1) 일부는 그렇지 않으며 2) 미래에 일어날 일만 추측 할 수 있습니다.


1-항상 ... 기본적으로 빅 엔디안 인 플랫폼을 포함합니다.

2-실제로 "안전"이란 무엇입니까? 하드웨어 플랫폼의 미래 방향을 예측하도록 요청하는 경우 객관적으로 대답 할 수 없습니다.


3

엔디안 만이 유일한 고려 사항은 아닙니다. 정수의 크기가 있고 보내거나받을 구조체의 패킹 등이 있습니다.

이 모든 것을 무시할 수 있습니다. 아무도 당신을 강요 할 수 없습니다. 반면에 안전하고 신뢰할 수있는 방법은 외부 형식을 문서화 한 다음 프로세서, 프로그래밍 언어 및 프로그래밍 언어 구현에 관계없이 외부 형식을 올바르게 읽거나 쓰는 코드를 작성하는 것입니다.

일반적으로 코드가 많지 않습니다. 그러나 코드를 읽는 사람들은 자신이 단서가 없다고 의심하지 않으며 외부 데이터 교환에 대해 전혀 알지 못하며 일반적으로 신뢰할 수없는 코드를 작성합니다.


3

C의 표준 BSD 네트워킹 스택에는 네트워크 기본 시스템 (big endian)에서 no-ops로 확장되는 hton/ ntoh기능 ( network-to-host/ host-to-network)이 있습니다. 네트워크 네이티브 바이트 순서가 거의 엔디안이 아닌 시나리오의 경우 이에 대응하는 고유 한 항목이 필요합니다.

이것이 가장 강력한 방법입니다.

그것은 전통적이지 않지만, 나는 아무 문제가 없습니다. 네트워크로 연결된 컴퓨터는 항상 바이트 스트림을 얻으므로 해당 바이트를 해석하는 방법에 대한 프로토콜에 동의해야합니다. 이것은 단지 일부입니다.


3

서버간에 데이터를 전송하는 데 사용되는 다양한 프로토콜은 리틀 엔디안 번호를 사용합니다.

  1. BSON
  2. 프로토콜 버퍼
  3. Capn Proto

리틀 엔디안 번호가 있고 일부는 빅 엔디안 번호가있는 다양한 형식에 대한 자세한 내용 은 https://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats를 참조 하십시오 .

작은 엔디안 숫자를 기반으로 한 프로토콜을 사용하는 데 아무런 문제가 없습니다. 빅 엔디안 시스템은 리틀 엔디안 시스템이 빅 엔디안 숫자를 읽을 수있는 것처럼 리틀 엔디안 숫자를 읽을 수 있습니다. 많은 사람들이 리틀 엔디 언 머신에서 빅 엔디안 숫자를 디코딩하는 추가 계산 비용을 피하기 위해 특별히이 작업을 수행했습니다.

이러한 기존 프로토콜 중 하나를 기반으로 프로토콜을 구축하면 이미 처리 한 문제에 대해 걱정할 필요가 없습니다. 빅 엔디안 플랫폼에서 코드를 실행하기로 결정하면 이러한 프로토콜을 구현하는 라이브러리가 값을 올바르게 디코딩하도록 자동으로 처리합니다.


2

빅 엔디안 시스템의 한 예는 라우터에 사용되는 MIPS입니다. ARM과 MIPS는 모두 엔디안으로 전환 할 수 있지만 MIPS는 네트워크 하드웨어를보다 쉽게 ​​만들 수 있기 때문에 종종 빅 엔디안입니다. 전체 단어를 버퍼링하지 않고 단어).

따라서 'Linux'의 의미에 달려 있지만 OpenWRT를 실행하는 라우터와 같은 작은 시스템에서 서버 응용 프로그램을 실행하려면 큰 엔디안 지원을 고려해야 할 수도 있습니다.

평소와 같이 가정을 단순화하는 것은 가정에 맞지 않는 무언가를 칠 때까지 완벽하게 합리적인 최적화입니다. 그러한 문제를 겪게되면 긴장을 푸는 것이 얼마나 고통 스러울 지 말할 수 있습니다.


0

나는 어떤 대답도 충분히 정확하다고 생각하지 않습니다. Wikipedia 에 따르면 엔디안은 단어를 구성하는 바이트의 순서입니다.

4 바이트를 가져 와서 int로 해석합니다. 작은 엔디안 시스템 중 하나는 바이트가 오른쪽에서 왼쪽으로 해석되며 빅 엔디안 시스템에서는 그 반대로 해석됩니다. 분명히 int를 해석하는쪽에 동의하는 것이 중요합니다.

json 또는 xml을 사용할 수있는 최신 네트워크 프로토콜을 약간 축소 할 수 있습니다. 이러한 형식 중 어느 것도 int를 4 바이트로 전송하지 않습니다. 그들은 수신 측에서 int로 구문 분석 될 텍스트로 데이터를 전송합니다.

따라서 엔디안은 json 또는 xml을 사용할 때 중요하지 않습니다. 우리는 여전히 tcp 헤더에 빅 엔디안을 사용해야하므로 네트워크 바이트 순서라고하지만 대부분의 프로그래머는 매일 그것들을 엉망으로 만들 필요가 없습니다.

오늘날 가장 널리 사용되는 인코딩은 utf-8이며 엔디안과 관련된 문제 에도 영향을받지 않습니다 .

그래서 그렇습니다. utf-8을 사용하여 전송 된 텍스트 기반 형식을 사용할 때 엔디안을 무시하는 것이 안전합니다.


두 개의 다운 투표와 의견이 없습니다. 큰.
Esben Skov Pedersen

1
나는 downvoter가 아니었지만이 대답은 완벽하게 유효한 질문을 무시하거나 무시하는 것처럼 보입니다. 일부 프로토콜이 텍스트 기반이라고해서 모든 프로토콜이 반드시 해당되는 것은 아닙니다.
피터 그린

2
페이로드 형식이 기본 프로토콜과 관련이 없다는 사실에 닿기 때문에 이것을 올렸습니다. 어떤 사람들은 구성 문제를 파고 싶어합니다.
Zdenek

0

빅 엔디안 시스템은 나갈 것 같습니다. 많은 전통적인 유닉스는 빅 엔디안을 사용했지만 x86의 리눅스를 선호하여 수년간 쇠퇴했습니다.

팔은 양 엔디안이지만 빅 엔디안 변형은 거의 보이지 않는 것 같습니다.

밉은 두 변종에 모두 존재합니다. 빅 엔디안 변형은 대부분 네트워킹 응용 프로그램에서 볼 수 있습니다 (역사적 이유로 인터넷 프로토콜은 일반적으로 빅 엔디안을 사용합니다).

ppc는 전통적으로 두 엔디안을 지원하는 일부 부분을 가진 빅 엔디 언이지만 IBM은 이제 64 비트 ppc에 대해 리틀 엔디안 모드를 추진하고있는 것으로 보입니다 (최근 ppc64el 포트를 데비안 및 우분투로 푸시했습니다).

sparc는 일반적으로 큰 엔디안이지만 다시 감소하는 것처럼 보입니다.

기존 프로토콜을 구현하는 경우 분명히 해당 사양을 따라야합니다. 만약 IETF가 새로운 프로토콜을 축복하기를 원한다면, 빅 엔디안은 기존 프로토콜에서 이미 사용하고 있기 때문에 더 쉬운 것 같습니다.

리틀 엔디 언 시스템에서는 작동하지 않는 매크로를 처음부터 입력하거나 빅 엔디안 시스템으로 이식해야 할 때까지는 귀찮게 할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.