소켓 프로그래밍의 htons() 함수
저는 소켓 프로그래밍을 처음 접하고 있으며 동작에 대해 이해하려고 합니다.htons()
인터넷에서 이런 튜토리얼이나 이런 튜토리얼을 읽은 적이 있어요.하지만 나는 이해할 수 없었다.htons()
바로 그렇습니다.다음 코드를 시도했습니다.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main( int argc, char *argv[] )
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
exit(1);
}
/* Initialize socket structure */
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
{
perror("ERROR on binding");
exit(1);
}
/* Now start listening for the clients, here process will
* go in sleep mode and will wait for the incoming connection
*/
listen(sockfd,5);
clilen = sizeof(cli_addr);
/* Accept actual connection from the client */
newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr,
&clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
/* If connection is established then start communicating */
bzero(buffer,256);
n = read( newsockfd,buffer,255 );
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
/* Write a response to the client */
n = write(newsockfd,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
return 0;
}
가치sin_port
로 나타났다.35091
디버깅을 하고 있는데 어떻게 하는지 모르겠어요.portno
에서 변경된5001
로.35091
누가 그 가격변화의 이유를 설명해 주시겠습니까?
이는 바이트가 메모리에 저장되는 순서와 관련이 있습니다.십진수5001
이0x1389
따라서 관련된 바이트는 다음과 같습니다.0x13
그리고.0x89
많은 디바이스는 리틀엔디안 형식으로 숫자를 저장합니다.즉, 최하위 바이트가 우선입니다.따라서 이 예에서는 메모리 내의 숫자가5001
로 저장됩니다.
0x89 0x13
그htons()
이 함수는 숫자가 네트워크 바이트 순서로 메모리에 저장되도록 합니다. 네트워크 바이트 순서는 최상위 바이트부터 시작합니다.따라서 숫자를 구성하는 바이트를 교환하여 메모리에 바이트가 순서대로 저장되도록 합니다.
0x13 0x89
little-endian 머신에서는 바이트가 스왑된 숫자는 다음과 같습니다.0x8913
16진수, 즉35091
10진 표기의만약 당신이 빅엔디안 기계로 작업하고 있다면htons()
번호는 이미 메모리에 올바른 방법으로 저장되어 있기 때문에 함수는 스와핑을 할 필요가 없습니다.
이러한 모든 스왑의 근본적인 이유는 네트워크 바이트 순서를 사용하기 위해 전송된 패킷이 필요한 사용 중인 네트워크 프로토콜과 관련이 있습니다.
htons
이host-to-network short
즉, 16비트의 짧은 정수, 즉 2바이트에서 작동합니다.
이 함수는 쇼트의 엔디안성을 스왑합니다.enianness)를 스왑합니다.
전화번호는 다음부터 시작합니다.
0001 0011 1000 1001 = 5001
endianness가 변경되면 다음 2바이트가 스왑됩니다.
1000 1001 0001 0011 = 35091
그htons()
함수는 호스트와 네트워크 바이트 순서 간의 값을 변환합니다.빅 엔디안과 리틀 엔디안과 네트워크 바이트 순서는 사용 중인 머신과 네트워크 프로토콜에 따라 다릅니다.
네트워크내에서 송신되는 바이트의 배열(엔디안니스)을 유지하기 위해서 행해집니다.
디바이스의 아키텍처에 따라 데이터를 메모리에 빅 엔디안 형식 또는 리틀 엔디안 형식으로 배열할 수 있습니다.네트워킹에서는 바이트 순서를 네트워크 바이트 순서라고 부르고 호스트에서는 호스트 바이트 순서라고 부릅니다.모든 네트워크 바이트 순서는 빅 엔디안 형식입니다.
가 little little htons()
의 메모리big endian 형식의 메모리 아키텍처에서는 하지 않습니다.
컴퓨터의 endianness는 다음과 같은 방법으로 프로그래밍 방식으로도 찾을 수 있습니다.
int x = 1;
if (*(char*)&x) {
cout << "Little Endian\n";
} else {
cout << "Big Endian\n";
}
'사용할 수 없다'를 할지 결정합니다.htons()
그렇지 않으면. 위 항상 .htons()
빅 엔디언
위해서, 건을 in in in in in in in in in in in in in in in in in in in in.portno
정수입니다.sockaddr
는 스트리밍 컨테이너입니다.
네트워크를 통해 데이터를 전송할 때는 시리얼라이제이션이라고 불리는 메커니즘에 의해 데이터를 스트림에 넣습니다.네트워킹의 맥락에서 일반적인 규칙은 숫자를 빅 엔디안 바이트 순서로 배치하는 것입니다. 즉, 내부 유형의 높은 값 자리수가 우선입니다.프로세서 아키텍처의 메모리 레이아웃도 Big Endian일 경우 정수의 메모리 표현은 하나씩 컨테이너로 보내집니다.그렇지 않으면 바이트 순서를 조정해야 합니다.그리고 이게 바로htons
값 : " " "sin_port
따라서 메모리 레이아웃은 평균 포트 번호의 빅 엔디안을 나타냅니다.
언급URL : https://stackoverflow.com/questions/19207745/htons-function-in-socket-programing
'source' 카테고리의 다른 글
Vue 3 패키지 버전이 일치하지 않음 (0) | 2022.08.17 |
---|---|
Features-vuex persistState 설치에도 불구하고 인증 상태가 유지되지 않음 (0) | 2022.08.17 |
'vue-test-utils' 및 'jest'를 사용한 'Created' 후크를 사용한 테스트 (0) | 2022.08.17 |
구체적으로, 말록의 결과를 캐스팅하는 것이 위험한 것은 무엇입니까? (0) | 2022.08.17 |
Java에서 JSON을 사용한HTTP POST (0) | 2022.08.17 |