컴퓨터시스템 11장에서 네트워크에 대한 기본 개념을 공부하며, 인터넷 검색과 책을 바탕으로 정리해본 포스팅입니다.
네트워크 바이트 오더: 빅엔디안
빅엔디안: 사람이 숫자를 읽는 순서와 같음. 디버깅이 편하다. 네트워크 바이트 오더링
리틀엔디안: 인텔포멧
[출처]https://genesis8.tistory.com/37 [리틀엔디안 & 빅엔디안]
[출처] https://blog.naver.com/myca11/221369799273
출처에서 서버와 클라이언트는 호스트라고 이야기했지만, 책에서는 서버와 클라이언트는 호스트가 아닌 프로세스이며, 같은 호스트 안에서 클라이언트-서버 트랜잭션이 있을 수 있다고 정의한다.
네트워크를 이용하기 위해 네트워크에 연결된(= 네트워크 주소가 할당된) 컴퓨터 혹은 그 외의 장치(Device)(= 노드)
네트워크 공간 상에 있는 모든 장치
따라서 모든 호스트는 노드이지만, 호스트가 아닌 노드는 존재한다. (ex 모뎀, 허브, 스위치등 중간자 역할을 하는 노드들)
네트워크 상에서 요청에 응답할 수 있는 프로세스
네트워크 상에서 요청하는 프로세스
- 클라이언트가 한 개의 요청(request)을 서버로 보낸다.
ex) 웹 브라우저가 파일을 필요로 할 때, 웹 서버로 요청을 보낸다.
같은 호스트 안에서도 클라이언트-서버 트랜잭션이 있을 수 있다.
※클라이언트-서버 모델은 클라이언트와 서버의 호스트로의 매핑에 관계없이 동일하다??
[출처] https://m.blog.naver.com/myca11/221389847130
별도의 호스트에서 돌아가는 서버와 클라이언트의 트랜잭션을 전제함
호스트에게 네트워크는 다른 I/O디바이스와 같다.
네트워크에서 수신한 데이터는 I/O와 메모리 버스를 거쳐 어댑터에서 메모리로, 대개 DMA 전송으로 복사된다. 마찬가지로 메모리에서 네트워크로 복사될 수도 있다.
이더넷은 가장 대중적인 LAN 기술이다. 이더넷 세그먼트는 몇개의 전선들과 허브로 구성된다. 대개 방이나 빌딩의 한 층 정도의 규모에 설치된다.
이더넷 세그먼트
여러 이더넷 세그먼트가 브릿지를 통해 연결되고,
모든 호스트는 모든 비트로 볼 수 있다.
네트워크에서 위치를 찾아갈 수 있는 유일한 값
IP주소 표기법
ex) 128.2.194.242 : 80 | 2 | c2 | f2 : 0x8002c2f2
1. 데이터는 프로세스 레벨에서 주고 받는다.
2. 호스트에서는 여러 프로세스가 동시에 동작한다.
3. 따라서 데이터가 네트워크를 통해 호스트에 도달했을 때, 요청에 맞는 프로세스까지 전달되어야 한다.
네트워크를 통해 데이터를 주고받는 프로세스를 식별하기 위해 호스트 내부적으로 프로세스가 할당받는 고유한 값
프로세스가 네트워크를 통해서 데이터를 주고받기 위해 여는 창구
https://en.wikipedia.org/wiki/Berkeley_sockets 소켓인터페이스
https://blockdmask.tistory.com/212 socket은 system call이다.
입력한 정보에 맞는 소켓 프로토타입의 주소를 받아서 그걸로 소켓을 만든다(뇌피셜)
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int getaddrinfo(const char *node, // e.g. "www.example.com" or IP
const char *service, // e.g. "http" or port number
const struct addrinfo *hints,
struct addrinfo **res);
hints : IPv4 | IPv6, TCP | UDP 여부
다음 함수에 hostname을 인자로 넘기면 IP주소를 뱉는다.
(cmd > hostname 명령어로 hostname 확인가능)
/*
** showip.c -- show IP addresses for a host given on the command line
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
if (argc != 2) {
fprintf(stderr,"usage: showip hostname\n");
return 1;
}
memset(&hints, 0, sizeof hints); // hint 구조체 초기화
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM; // TCP
if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
return 2;
}
printf("IP addresses for %s:\n\n", argv[1]);
for(p = res;p != NULL; p = p->ai_next) {
void *addr;
char *ipver;
// get the pointer to the address itself,
// different fields in IPv4 and IPv6:
if (p->ai_family == AF_INET) { // IPv4
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else { // IPv6
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
}
// convert the IP to a string and print it:
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf(" %s: %s\n", ipver, ipstr);
}
freeaddrinfo(res); // free the linked list
return 0;
}
getaddrinfo로 만든 res를 이용해 socket 생성
error 발생 시 -1 리턴
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
error 발생 시 -1 리턴
int listen(int sockfd, int backlog);
error 발생 시 -1 리턴
rio : 데이터를 저장하기 위한 안정적인 구조체