● TCP/IP 소켓통신의 흐름
● socket( )의 원형
int socket(int domain, int type, int protocol);
④반환값 ①프로토콜 패밀리 ②소켓형식 ③프로토콜
① 프로토콜 패밀리 ┬ PF_INET : IPv4인터넷
┣ PF_INET6 : IPv6 인터넷 프로토콜 체계
└ PF_UNIX : 유닉스
※ PF(프로토콜 패밀리) ≒ AF(어드레스 패밀리)
② 소켓형식 ┬ SOCK_STREAM : TCP형 소켓을 만들겠다.
└ SOCK_DGRAM : UDP형 소켓을 만들겠다.
③ 프로토콜 ┬ IPPROTO_TCP : TCP
└ IPPROTO_UDP : UDP
④ 반환값 ┬ 성공 : 음수가 아닌 값 (3, 4, 5…)
└ 실패 : –1
소켓형식과 프로토콜은 TCP형이면 TCP, UDP형이면 UDP로 같게 되므로,
소켓형식에 SOCK_STREAM을 넣은 뒤 프로토콜에 0을 넣으면 소켓형식에 맞춰 TCP protocol로 맞춰진다.
● 주소지정
● 범용 구조체
struct sockaddr { // 구조체 전체크기는 16Bytes
sa_family_t sa_family; // 패밀리는 unsigned short형
char sa_data[14]; // IP주소 4Bytes + Port번호 2Bytes (총 6Bytes)
} ;
sa_data[0]과 sa_data[1]에는 포트번호가 들어가고 sa_data[2] ~ sa_data[5]에는 IP주소가 들어간다.
IP주소가 먼저 들어가는게 아니라 port번호가 먼저 들어간다.
● IPv4 주소용 구조체
struct sockaddr_in { //sockaddr과 마찬가지로 16Bytes
sa_family_t sin_family; //주소패밀리
in_port_t sin_port; // 포트번호
struct in_addr sin_addr; //IP주소
char sin_zero[8]; // sockaddr과 호환을 위한 더미
};
범용과 다른 점은 IP주소와 포트번호가 따로 나뉘어져 있다는 것이다.
sa_family_t 자료형은 2Bytes이고 in_port_t자료형도 2Bytes이고 char형 sin_zero[8]배열은 8Bytes이고,
IP주소를 담는 in_addr구조체는 아래와 같이 4Bytes이므로 모두 합하면 16Bytes가 되어,
주조지정 범용구조체 sockaddr과 사이즈가 같아 호환이 된다. 자료형은 다르지만 선형메모리구조에서 순서는 같으므로 호환된다고 한다.
struct in_addr {
uint32_t s_addr; //인터넷주소32bit
};
unsigned int형으로 4Bytes 자료형으로 선언되어 있다.
IP주소의 최대값은 255.255.255.255이니 각 자리가 1Byte씩 총 4Bytes(32bit)인 것이다.
● helloworld_server.c 코드 분석
17행: struct sockaddr_in serv_addr;
구조체 자료형 변수명
serv_addr변수를 sockaddr_in자료형으로 구조체선언.
23행: serv_sock = socket(PF_INET, SOCK_STREAM, 0);
-1이면 에러처리(예외처리) IPv4 TCP TCP
client도 마찬가지로 TCP프로토콜 소켓 인스턴스를 생성.
30행: memset(&serv_addr, 0, sizeof(serv_addr));
대상주소 채울 값 몇 바이트 채울지
serv_addr구조체를 0으로 초기화함.
31행: serv_addr.sin_family = AF_INET;
프로토콜패밀리 IPv4주소체계
4Bytes IP주소와 2Bytes 포트번호를 사용하는 주소체계로 설정.
32행: serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
IP주소 localhost
INADDR_ANY에 대해 네이버 검색해보니..
localhost이고 자신의 IP가 아닌 0x0000으로 되어 있다가 클라이언트가 connect( )로 요청하면 클라이언트IP로 바뀐다?
그래서 구글에서 검색하니…
어떤 IP주소의 클라이언트가 접속하여도 연결할 수 있게 하고 싶을 때 쓴다고 한다.
클라이언트측 IP는 서버의 IP를 입력하면 된다.
PC 한 대로 시험할 때는 loopback주소 “127.0.0.1” localhost도 “127.0.0.1”로 정의되어 있단다.
33행: serv_addr.sin_port = htons(9190);
포트번호
포트번호를 9190으로 한다.
버퍼(Buffer) |
● HexaView로 읽어 들인 File의 Binary값은 하드디스크의 실제 데이터인가? 답: 아니다.
하드디크스 하드디스크에 있는 모든 데이터가 아닌 read()로 가공되어 나온 데이터가 Buffer에 저장이 되고 후에 write()로 모니터에 출력.
write()로 모니터에 출력할 때도 버퍼의 값이 아닌 다른 여러 값이 섞여 있을 수 있다.
● 로딩(Loading) : 하드디스크 –> 메모리에 적재 시키는 일.
● 버퍼(Buffer) : 크기가 1Byte든 512Bytes든 모두 버퍼이다.
● 이더넷버퍼(mtu) : 너무 작으면 다운 받는 파일이 조각이 많이 나서 느려진다. 온라인게임시 렉이 걸릴 수도 있다.
# ifconfig명령으로 확인해보면…
mtu값이 16436인 것을 알 수 있다.
mtu값을 200까지 낮추어 보니 업/다운 속도가 느려지고 온라인게임에서 응답속도는 빨라졌다.
버퍼의 사이즈를 줄이면 자주 왕복해야 하니 느려진다. 그렇다고 무진장 키운다고 빨라지는 것은 아니었다.
● 패킷(Packet) : 헤더 + window(데이터)
전송속도에 따라 window크기 가변.(슬라이딩 window)
● 워드같은 프로그램은 파일을 통채로 메모리에 로딩하니 버벅거리고 메모리를 많이 차지함.
왜 버퍼사이즈가 큰데 버벅거리는가? 사용자가 얼마나 큰 파일을 로딩할지 모르니 항상 모두 메모리에 올리므로 버벅거림.
임베디드C p.353 예제 p11-10 中 |
프로그램 시작 후 파일을 여는 부분…
1: //출력파일의 생성
2: if((outfd = creat("d11-10.out", S_IREAD | S_IWRITE)) < 0)
3: {
4: printf("file create error!\n");
5: return -1;
6: }
7:
8: close(outfd); //파일의 속성을 기록하기 위해서 닫음
9:
10: //출력파일을 쓰기 위해서 오픈
11: if((outfd = open("d11-10.out", O_WRONLY)) < 0)
12: {
13: printf("file open error!\n");
14: return -1;
15: }
2행 : creat( )로 파일을 열고,
8행 : close( )로 파일을 닫는다.
11행 : open( )로 다시 그 파일을 연다.
왜? creat( )로 파일을 생성 후 close( )로 닫고 open( )으로 다시 여는 이유는 무엇인가?
순서…
① 읽기와 쓰기허용 속성을 파일에 부여하며 생성 –rw
② 파일 닫음.
③ 쓰기전용으로 파일을 열기
내 생각…
open( )로 O_CREAT oflag를 사용하지 않고 열 때나,
touch명령처럼 파일 생성만 하고 싶을 때 creat( )를 사용하면 된다는 예제가 아닐까 생각된다.
리눅스파일속성은…
# chmod 777 [파일명]
chmod명령으로 파일의 속성을 바꿀 수 있으나 공유폴더에 있으면 사용자권한밖에 안되고,
/home 디렉토리에서 하니 기타사용자도 되었다.
● 예제 p11-10을 실행하여 입력한 값이 기록된 파일을 생성하고 HexaView로 열어 분석하자.
1, suman, 81/06/24
2, kuku, 06/05/11
3. lala, 89/12/06
데이터를 입력하여 파일에 기록한 뒤에 HexaView로 그 파일을 열어 보니 상기의 그림과 같이,
ID는 노란색 4Bytes,
name은 빨간색 20Bytes,
year, month, day 모두 각 4Bytes씩 총 12Bytes로 구성되어 있다는 것을 알 수 있다.
첫 번째 ID 1번만 보면 이름 옆에 09행에 00이라는 데이터가 기록되어 있다. 0x00은 NULL문자로 문자열의 끝을 나타낸다.
이 NULL문자 이후는 모두 쓰레기값이다.
두 번째 ID 2번을 보면 1번과 마찬가지로 똑같은 구조로 되어 있다는 것을 알 수 있다.
이런 데이터를 RAW데이터라고 부른다.
RAW DATA는 가공하지 않은 원데이터를 말한다.
// PE와 ELF구조체에 관한 이야기는 나중에…
순차접근방식과 임의접근방식 |
● 저수준 랜덤엑세스 함수
//file descriptor, offset값, 기준위치를 인자로 넘겨주면 파일커서의 위치가 바뀐다.
off_t lseek(int fildes, off_t offset, int whence);
SEEK_SET 변위는 offset바이트로 설정 (파일시작점기준)
SEEK_CUR 변위는 현재위치 + offset (현재 커서위치 기준)
SEEK_END 변위는 파일크기 + offset (파일의 끝 기준)
//너무 급해서 별 생각없이 적었습니다. 태클 많이 걸어주세요.
'코스웨어 > 11년 내장형하드웨어' 카테고리의 다른 글
[내장형]김동화 2011년7월 5일 수업내용 (14) | 2011.07.05 |
---|---|
[내장형]이성재 2011년7월4일 수업내용 (15) | 2011.07.04 |
[내장형]최남식-2011년7월1일 수업내용 (11) | 2011.07.02 |
[내장형]김정환 - 2011년 06월 30일 일일 보고서 (10) | 2011.06.30 |
[내장형]김수만_포스트에 C Code를 웹브라우저에서 보기 좋게 삽입하기 (6) | 2011.06.28 |
[내장형]최남식-가입인사 (0) | 2011.06.28 |
[내장형]최성태_20110628 수업내용 (24) | 2011.06.28 |
[내장형]심재원-가입인사. (0) | 2011.06.28 |