네트워크를 통해 데이터를 전송하는 데 QUdpSocket을 사용하는 프로그램을 작성하고 있습니다. 이것은 나의 첫번째 소켓 프로그램이고 Endianness라는 흥미로운 문제를 보았습니다.Qt 소켓 및 엔디안 방식
내 소켓 라이브러리로 QNetwork를 사용할 때 내 실제 질문에 엔디 언 어를 걱정해야합니까? 걱정할 필요가 없다면 엔딩 문제를 제대로 피하기 위해 무엇을해야합니까?
미리 감사드립니다.
네트워크를 통해 데이터를 전송하는 데 QUdpSocket을 사용하는 프로그램을 작성하고 있습니다. 이것은 나의 첫번째 소켓 프로그램이고 Endianness라는 흥미로운 문제를 보았습니다.Qt 소켓 및 엔디안 방식
내 소켓 라이브러리로 QNetwork를 사용할 때 내 실제 질문에 엔디 언 어를 걱정해야합니까? 걱정할 필요가 없다면 엔딩 문제를 제대로 피하기 위해 무엇을해야합니까?
미리 감사드립니다.
일반적으로 한 컴퓨터에서 다른 컴퓨터로 한 바이트보다 큰 정수를 전송할 때 엔디 언 (바이트 순서)에 대해 걱정할 필요가 있습니다. C/C++에서는 16 비트, 32 비트 또는 64 비트 정수를 보내는 경우 정수를 네트워크 바이트 순서 (Big-Endian이라고도 함)으로 변환해야합니다.). 수신 측의 컴퓨터는 들어오는 정수를 호스트 바이트 순서으로 변환해야합니다. 호스트 컴퓨터는 기본적으로 호스트 시스템이 사용하는 바이트 순서입니다. 이것은 대개 htons
및 ntohs
라이브러리 함수 시리즈를 사용하지만 Qt 라이브러리를 사용하면 qToBigEndian
및 qFromBigEndian
함수를 사용할 수도 있습니다.
ASCII 또는 UTF-8 텍스트를 보낼 때 엔디안을 걱정할 필요가 없습니다. 이러한 형식은 멀티 바이트 데이터 형식이 아닌 개별 바이트 시퀀스로 구성되기 때문입니다.
다른 엔디안을 사용하는 두 시스템간에 바이너리 데이터를 전송하는 경우 걱정할 필요가 있습니다.
네트워크 소켓은 데이터를 변경하지 않고 출하합니다. 다른 컴퓨터에서 전송 된 바이트가 특정 순서로 있다고 가정하면이를 관리해야합니다.
이미지와 같이 알려진 형식으로 데이터를 전송하는 경우 일반적으로 이미지 형식은 머리글에 어떤 순서로 표시되는지 표시하기 위해 헤더에 내용이 있으며 판독기/기록기 라이브러리가이를 처리합니다. 자신 만의 바이너리 형식을 발명한다면, 그것은 당신에게 달려 있습니다. 크기를 고려해야 할 수도 있습니다. 다른 컴퓨터의 int는 몇 바이트입니까?
좋은 소식은 대부분의 기계가 Intel이며 대부분의 응용 프로그램에서 ASCII 형식으로 적은 양의 데이터를 출하 할 수 있다는 것입니다.
인텔 CPU는 리틀 엔디안을 사용합니다. 그 밖의 대부분은 빅 엔디안입니다. 기본 네트워크 바이트 순서는 빅 엔디안입니다.
엔디안이 문제가되는지 테스트하려면 0x12345678 값을 보내고 동일하게 또는 0x78563412로 설정하는지 확인하십시오. 수신 컴퓨터의 값이 나중 값이면 엔디안은 두 시스템간에 동일하지 않습니다.
엔디 언스에 대한 정보는 this wikipedia article을 확인하십시오.
//이 테스트는 적어도 2의 INT의 크기를 가정 : 당신이 그것을 원하는 경우에
인텔 CPUS는 리틀 엔디안을 사용합니다. 이는 OS의 기능이 아닙니다. –
Windows에서 리틀 엔디안을 사용한다고 말하면 오해의 소지가 있습니다. "기타 모든 제품"은 빅 엔디안을 사용합니다. 엔디안은 OS가 아닌 프로세서 아키텍처의 속성입니다. 대부분의 가정용 컴퓨터는 리틀 엔디안입니다. 인텔 및 AMD x86 프로세서는 리틀 엔디안이기 때문입니다. 여기에는 Windows 이외의 Linux 또는 다른 OS를 실행하는 x86 컴퓨터가 포함됩니다. –
예 인텔 맥은 리틀 엔디안이고, PowerPC는 빅 엔디안 (칩은 전환 가능하지만 Mac은 기본 모드를 사용했습니다.), ARM (iStuff)은 구현이 정의되었습니다 –
여기에, 큰 엔디안에 대한 간단한 테스트입니다.
static const int testValue = 1;
#DEFINE의 is_bigendian() (((CHAR) & testValue) == 0)
부울 CD_is_bigendian (공극) { 복귀 is_bigendian(); }
미래에이를 참조하는 사용자는 원하는 것으로 생각할 수 있지만 실제로 : https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html – josaphatv
나는 이것이 오래 전 대답했지만, 나는 그것에 덧붙였다 고 생각했다.
대신 엔디안 변환 기능을 사용하여, 당신은 쉽게 많이 내 의견에보다 직관적 이다, (어떤 QIODevice 사용) QDataStream 기능을 사용할 수 있습니다. 물론, 그것은 송신자와 수신자 모두에서 QDataStream을 사용하게 할 것이지만,이 경우에는 그만한 가치가 있습니다.
사용 예제, 이미지를 보내는 누군가 다른 사람의 샘플 :
QDataStream & operator<< (QDataStream& stream, const QImage& image);
QDataStream & operator>> (QDataStream& stream, QImage& image);
(그 중 둘은 이미 Qt를 내에서 구현됩니다.)
QTcpSocket *tcp = ...;
QImage img = ...;
QDataStream(tcp) << img;
스트리밍을하는 경우 언제든지이 작업을 수행 할 필요는 없습니다. o 모든 바이트를 hton으로 변환 한 다음 다시 다시 변환하는 것은 이해가되지 않습니다. 따라서 수신 시스템이 데이터의 어느 쪽이 길 었는지 알 수 있도록 코드를 만드는 것이 좋습니다. –
잘못된 UTF-8은 가변 폭 인코딩으로 모든 유니 코드 문자를 나타낼 수 있으며 최대 4 바이트까지 사용할 수 있습니다. –
아니요, 이해가 잘못되었습니다. UTF-8은 가변 폭 인코딩이지만 UTF-16 또는 UTF-32와 달리 가변 길이 문자가 정렬 된 바이트 시퀀스로 구성되어 있기 때문에 엔디안의 영향을받지 않습니다. 최소 단위는 2 (또는 4) 바이트의 2 진 정수입니다. 그의 바이트 순서는 아키텍처 엔디안에 의해 결정됩니다. –