struct sockaddr
{
unsigned short sa_family; /*인터넷 주소 패밀리 2byte*/
char sa_data[14]; /* port 번호(short형 : 2byte) + ip 주소 (long형 4byte)*/
};
struct socketaddr_in
{
unsigned short sin_family; /* Internet protocol */
unsigned short sin_port; /* Address port (16bits) */
struct in_addr sin_addr; /* Internet address (32bits) */
char sin_zero[8]; /* Not used */
};
socketaddr_in으로 사용자에게 값을 입력받아 sockaddr 자료형으로 변환하여 사용
Intel 계열 CPU는 Little Endian 방식 채택
네트워크에서는 BIG Endian 방식 채택
예제
#include <stdio.h>
int main(void) { short host_port_order= 0x1234; short net_port_order;
long host_add_order = 0x12345678; long net_add_order;
net_port_order = htons(host_port_order); net_add_order = htonl(host_add_order);
printf("Host ordered port : %x \n", host_port_order); printf("Network ordered port : %x \n\n", net_port_order); |
inet_addr()
inet_addr() 예제
#include <stdio.h> #include <arpa/inet.h>
int main() { char* addr1 = "1.2.3.4"; char* addr2 = "1.2.3.256"; unsigned long conv_addr;
conv_addr = inet_addr(addr1); if(conv_addr==INADDR_NONE) printf("error occur : %d \n", conv_addr); else printf("unsigned long addr(network ordered) : %x \n", conv_addr);
conv_addr d= inet_addr(addr2); if(conv_addr==INADDR_NONE) printf("error occur : %d \n", conv_addr); else printf("unsigned long addr(network ordered) : %x \n", conv_addr);
return 0; } |
inet_aton 예제
#include <stdio.h> #include <arpa/inet.h>
void error_handling(char* message);
int main() { char *addr = "1.2.3.4"; struct sockaddr_in addr_inet;
if(!inet_aton(addr,&addr_inet.sin_addr)) error_handling("ERROR");
printf("unsigned long address(network orderd) : %x \n\n",addr_inet.sin_addr.s_addr);
return 0; }
void error_handling(char *message) { fputs(message, stderr); fputs('\n',stderr); exit(1); } |
1. inet_addr()함수
이 함수는 Dotte-Decimal Notation 형식을 빅엔디안 32비트 값으로 변환시켜줍니다.
unsigned long inet_addr(const char *string);
위가 함수의 원형인데 함수 파라미터 값에 IP주소 문자열의 시작주소를 넣어주면 이 함수가 알아서 빅엔디안 32비트 unsigned long 형의 값으로 만들어줍니다.
성공하면 빅엔디안 형식의 32비트 값을, 실패하면 INADDR_NONE을 리턴합니다.
INADDR_NONE은 실제로 -1로 선언되어 있습니다.
2. inet_aton()함수
이 함수는 기본적으로 주소 문자열을 빅엔디안 32비트 값으로 변환 시켜주는건 inet_addr()함수와 같지만 다른 점이 있습니다.
inet_addr()함수는 변환된 값을 sockaddr_in 구조체의 맴버변수 안에 또 선언된 in_addr 구조체에 값을 대입해주어야 합니다. 하지만 inet_aton()함수는 자동으로 값을 대입시켜줍니다.
따라서 따로 대입해야 할 필요가 없어집니다. 먼저 이것이 함수의 원형입니다.
int inet_aton(const char *string, struct in_addr *addr);
첫번째 파라미터 값은 주소 문자열이 있는 포인터변수가 들어가고 두번째 파라미터 값은 구조체 맴버변수중 주소값이 들어가는 맴버변수의 주소값을 넣어주시면 됩니다.
함수를 성공시키면 0이 아닌값, 실패하면 0이 리턴됩니다.
이 함수는 inet_addr()함수보다 편리하게 사용할 수 있습니다.
서버에서 접속하는 클라이언트 주소 출력하기
struct sockaddr_in client_addr; //선언
클라이언트주소는 client_addr.sin_addr.s_addr 저장되어있는것을
ntohl를 사용하여 Little Endian 방식으로 바꿔서 출력
서버의 연결에 따른 분류
1. 연결형 서버 : TCP를 이용
2. 비연결형 서버 : UDP를 이용
서버의 서비스에 따른 분류
1. Iterative 서버
- 클라이언트의 서비스 요구를 순서대로 처리해 주는 서버
- request 처리시간이 짧거나 별로 문제가 되지 않는 경우에 사용
- Iterative 서버는 프로그램 구현이 비교적 간단
2. Concurrent 서버
- 여러 요구를 동시에(concurrently) 서비스할 수 있는 서버
- 새로운 클라이언트가 접속될 때마다 서비스를 담당할 프로세스를 새로 만드는 방법이 있으나 이 방법은 클라이언트 수가 늘어남에 따라 프로세스 수도 계속 늘어남
※ 하나의 프로세스가 여러 서비스를 동시에 처리 방법 apparent concurrent 서버
Iterative 서버 예제
1. 하나의 클라이언트가 접속을 하면 connect함수를 호출하면 연결
2. 서버의 연결요청 대기 큐에 들어감
3. accept 함수가 한 개씩 소켓을 생성하여 connetc함수를 클라이언트에게 리턴해주면 연결완료
'소프트웨어 > 네트워크' 카테고리의 다른 글
send, sendto, write, recv, recvfrom, read (0) | 2011.07.15 |
---|---|
Little Endian / Big Endian (0) | 2011.07.12 |