2011. 7. 29. 02:01
Q.

p.130~131 op_client.c 부분에서 막혀서 이렇게 글을 씁니다.

학교 서버 리눅스 환경에서 이 소스를 돌려보았습니다.. 그런데..

클라이언트 쪽에서 연결도 됐고, Operand conunt 까지 입력이 되는데

Operand 1 부터 입력을 하면 버스 오류 (core dumped)라는 게 뜨네요..

아무리 찾아봐도 잘 모르겠어서 올립니다.. ㅠㅠ

아무래도 39행인 scanf("%d", (int*)&opmsg[i*OPSZ+1]); 에서 오류가 나는 것 같은데요.

왜 그럴까요 ? ㅠㅠ

미심적어서 소스를 scanf("%d", (int*)&opmsg[i*OPSZ+4]);

이렇게 고쳐보면, 그 뒤 값들은 받아지긴 하지만, 전체적인 로직과, 구현 목적(char 문자에 계산할만큼 숫자를 담아라)이

달라지기에...

34라인의 opmsg[0] = (char)opnd_cnt; 여기서 char형인 1바이트만큼만 기록되야 맞는게 아닌가요?

인터넷에서 대략 찾아보니 메모리가 덤프되는게.. 뭐 겹쳐써지고.. 이런 말도 있고..... ㅠㅠ

알려주세요!!!!!! ㅠㅠㅠㅠㅠ



A.

안녕하세요 해결하지 못해 답변이라 하긴 뭐하지만...

빅엔디안 시스템이 원래 이런 것인지는 잘 모르겠습니다.

op_client.c에서,
문제가 발생하는 부분만 요약했습니다.

1 #include <stdio.h>
2 #include <string.h>
3
4 #define BUFMAX 9
5
6
7 int main(void){
8 int i;
9 char buf[BUFMAX];
10
11 memset(buf, 0, BUFMAX);
12 scanf("%d", (int *)&buf[1]);
13
14 for(i=0; i<BUFMAX; i++)
15 printf("buf[%d]=%0x , %p\n",i, buf[i], &buf[i]);
16
17 return 0;
18
19 }



12번 줄이 문제가 되는 부분인데,
리틀엔디안 시스템의 리눅스에서는 (int *)&buf[숫자]의 숫자 부분을
범위 내에서 마음대로 줄 수가 있었습니다. 원하는 대로 포인터가 갑니다.

그러나, 솔라리스만 이런 것인지 빅엔디안 시스템이 다 이런 것인지는 모르겠지만,
솔라리스 빅엔디안 시스템에서는 반드시 (int *)&buf[숫자]부분의 숫자가 0, 4, 8 이런 식으로
int의 크기에 맞춰서 써줘야 했고, 중간 숫자 1, 2, 3, 5, 6, 7 같은 숫자를 넣는다면
반드시 Core Dump가 일어났습니다.


** 숫자를 0을 주었을 때...
$./a.out
9
buf[0]=0 , ffbff9a8
buf[1]=0 , ffbff9a9
buf[2]=0 , ffbff9aa
buf[3]=9 , ffbff9ab <-- 하위 바이트의 값을 높은 번지 주소에 저장.
buf[4]=0 , ffbff9ac
buf[5]=0 , ffbff9ad
buf[6]=0 , ffbff9ae
buf[7]=0 , ffbff9af
buf[8]=0 , ffbff9b0
$


** 숫자를 1을 주었을 때...
$./a.out
3
Bus error (core dumped)
$



*** 리틀엔디안 시스템의 리눅스에서 숫자 1주고 실행했을 때
$ ./a.out
3
buf[0]=0 , 0xbfb10b83
buf[1]=3 , 0xbfb10b84 <--- buf의 1번 주소에 바로 들어갑니다.
buf[2]=0 , 0xbfb10b85 하위 바이트의 값을 낮은 번지 주소에 저장.
buf[3]=0 , 0xbfb10b86
buf[4]=0 , 0xbfb10b87
buf[5]=0 , 0xbfb10b88
buf[6]=0 , 0xbfb10b89
buf[7]=0 , 0xbfb10b8a
buf[8]=0 , 0xbfb10b8b
$


솔라리스 빅엔디안 시스템에서
op_client.c, op_server.c의 소스를 그대로 쓸 수 없는 것은
맞는 것 같습니다.


A2.

그냥 되도록 바꿨습니다.

서버 프로그램 쪽에서는 바꿀 코드가
int형으로 선언된 opnd_cnt를
char형으로 바꿔주고,


클라이언트 프로그램 쪽에서는

typedef union charInt{
char intByte[4];
int cInt;
}UsrInt;

위와 같이 scanf()를 통해 받을 정보를
임시저장할 공용체 형을 정의하고 후에 선언한 뒤,
이것을 사용해서 클라이언트에서
피 연산자 값을 입력 받는 부분을 아래와 같이 고쳐서

for(i=0; i<opnd_cnt; i++)
{
printf("Operand %d: ", i+1);
scanf("%d", &usrInt.cInt);

opmsg[i*OPSZ+1]=usrInt.intByte[0];
opmsg[i*OPSZ+2]=usrInt.intByte[1];
opmsg[i*OPSZ+3]=usrInt.intByte[2];
opmsg[i*OPSZ+4]=usrInt.intByte[3];
}

opmsg[]에 수동으로 값을 맞춰 넣어주니..

솔라리스에서도 잘되네요..


출처: http://cafe.naver.com/cstudyjava.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=20401&

초보01님의 답변^^ 친절한 답변 감사드립니다 - 소켓 공부ing...

Posted by Triany
2011. 7. 25. 13:59
[C표준함수] memset() 함수
글쓴이 : 정민구 날짜 : 09-03-26 21:19 조회 : 6046 
memset 
메모리를 지정한 문자로 채웁니다. 

Declaration 
void *memset( void *dest, int c, size_t count ) 

Return value 
성공 - 채워진 메모리 주소(dest 매개 변수) 반환 
실패 - 없음 


Parameters 
dest  - 채울 메모리의 주소 
c    - 채울 문자 
count - 채우려고 하는 문자 개수 


Detail descriptions 
memset()는 버퍼를 똑같은 "문자"로 채울 때 사용합니다. 명확하게 문자라고 표현했듯이 단위는 바이트입니다. memset()는 문자를 저장하는 char 배열뿐만 아니라 모든 종류의 배열에 대해서 사용할 수 있습니다. 그러나, 단위가 바이트이기 때문에 배열 요소의 자료형에 따라 세심한 주의가 필요합니다. 

대부분의 배열은 초기 상태로 0을 갖습니다. 그래서, {} 초기화를 사용해서 모든 요소에 대해 0을 지정하도록 합니다. 그러나, {} 초기화는 배열을 선언할 때 한번만 사용할 수 있고, 이후에는 일일이 모든 요소에 대해 0을 넣어줘야 합니다. 이와 같이 모든 요소를 0으로 채울 때, 배열 종류에 상관없이 사용하는 함수가 memset()입니다. 




출처 : 
http://www.itdi.co.kr/onuri/bbs/board.php?bo_table=02_1&wr_id=9

소켓 프로그래밍 당시 이 함수가 계속하여 쓰이기에 알아보았다.
주로

memset(&addr, 0 sizeof(addr));
이런식으로 sockaddr_in addr;로 선언한 주소체계를 addr의 size만큼 0으로 채우는 것을 볼 수 있다. 
Posted by Triany
2011. 7. 22. 18:50
01. TCP보다 UDP가 빠른 이유는 무엇인가? 그리고 TCP는 데이터 전송을 신뢰할 수 있지만 UDP는 신뢰할 수 없는 이유는 또 무엇인가?
UDP는  TCP에서 ACK와 같은 응답 메시지를 보내는 일도 없고, SEQ와 같이 패킷에 번호를 부여하는 일도 없다.
UDP는 흐름제어가 존재하지 않는다.

[TCP가 UDP에 비해 느린 이유 ]
- 데이터 송수신 이전, 이후에 거치는 연결설정 및 해제 과정
- 데이터 송수신 과정에서 거치는 신뢰성 보장을 위한 흐름 제어

02. 다음 중 UDP의 특성이 아닌 것을 모두 고르면? b
      .. 책에 풀었음...


03. UDP 데이터 그램이 최종 목적지인 상대 호스트의 UDP 소켓에 전달되는데 있어서 IP가 담당하는 부분과 UDP가 담당하는 부분을 구분 지어 설명해 보자.
IP의 역할 : 호스트 B를 떠난 UDP 패킷이 호스트 A에 전달되도록 하는 것.
UDP의 역할 : 호스트로 수신된 UDP 패킷을 PORT 정보를 참조하여 최종 목적지인 UDP 소켓에 전달.

04. UDP는 일반적으로 TCP보다 빠르다. 그러나 송수신하는 데이터의 성격에 따라서 그 차이는 미미할 수도 있고, 반대로 매우 클 수도 있다. 그렇다면 어떠한 상황에서 UDP는 TCP보다 매우 좋은 성능을 보이는지 설명해 보자.
TCP 기반으로 송수신 되야 하는 경우 : 압축파일의 경우(일부 파일이 손상되면 압축 해제의 어려움이 있음)
UDP 기반으로 송수신 되는 것이 좋은 경우 : 인터넷 기반으로 실시간 영상 및 음성을 전송하는 경우(멀티미디어 데이터)



05. 클라이언트의 TCP소켓은 connect 함수를 호출할 때 자동으로 IP와 PORT가 할당된다. 그렇다면 bind 함수를 호출하지 않는 UDP 소켓은 언제 IP와 PORT가 할당되는가?
snedto 함수 호출 시까지 주소정보가 할당되지 않았다면, sendto 함수가 처음 호출되는 시점에 해당 소켓에 IP와 PORT번호가 자동으로 할당된다.

UDP 기반의 데이터 송수신과정에서는 입출력 함수의 호출횟수를 일치시켜야 함..

06. connect 함수의 호출문장은 TCP 클라이언트의 경우 반드시 삽입해야 하는 문장이다. 그러나 UDP의 경우는 선택적으로 삽입이 가능하다. 그렇다면 UDP에서 connect 함수를 호출하면 어떠한 이점이 있는가?
[sendto 함수 호출을 통한 데이터의 전송과정]
1단계. UDP 소켓에 목적지의 IP와 PORT 번호 등록
2단계. 데이터 전송
3단계. UDP 소켓에 등록된 목적지 정보 삭제

명확히 전송될 주소와 포트번호를 안다면, connect를 사용하는 것이 더 유리한데 이는, 전송과정중 1단계와 3단계에서 걸리는 시간을 줄임으로써 성능향상을 기대할 수 있다. 




07. 본문에서 보인 예제 uecho_server.c와 uecho_client.c를 참고해서 서버와 클라이언트 상호간에 한번씩 메시지를 주고받는 형태로 대화를 진행하는 예제를 작성해 보자. 단 주고 받는 대화는 콘솔창에 출력되어야 한다.

 --> 구현함
Posted by Triany
2011. 7. 21. 19:12



01. TCP 소켓의 연결설정 과정인 Three-way handshaking에 대해서 설명해 보자. 특히 총 3회의 데이터 송수신이 이뤄지는데, 각각의 데이터 송수신 과정에서 주고 받는 데이터에 포함된 내용이 무엇인지 설명해보자.


TCP의 내부 동작 원리 1: 상대 소켓과의 연결
TCP 소켓은 연결설정 과정에서 총 세 번의 대화를 주고 받는데, 이를 가리켜 Three-way handshaking 이라 한다.

[Three-way handshaking과정]


 

 

[SYN] SEQ : 8000, ACK : -
처음 연결요청에 사용되는 메시지 이기에 이 메시지를 가리켜 ‘SYN’이라 한다
.
데이터 송수신에 앞서 전송되는 동기화 메시지

[SYN + ACK] SEQ : 15000, ACK : 8001
처음 client가 전송한 패킷에 대한 응답 메시지(ACK 8001)과 함께 호스트 B의 데이터 전송을 위한 동기화 메시지(SEQ 15000)을 함께 묶어서 보낸다. 이런 유형의 메시지를 SYN+ACK라 한다.

[ACK] SEQ : 8000 ACK : 15001
15001 패킷을 전송하길 요청.

 


02. TCP는 데이터의 전송을 보장하는 프로토콜이다. 그러나 인터넷을 통해서 전송되는 데이터는 소멸될 수 있다. 그렇다면 TCP는 어떠한 원리로 중간에 소멸되는 데이터의 전송까지 보장을 하는 것인지 ACK와 SEQ를 대상으로 설명해 보자.

ACK
번호 -> SEQ 번호 A+ 전송된 바이트 크기 + 1
!
중간에 패킷이 소멸되는 경우
= > 데이터 손실에 대한 재전송을 위해서, TCP 소켓은 ACK 응답을 요구하는 패킷 전송 시에 타이머를 동작시킨다. 그리하여 해당 타이머가 Time-Out 되었을 때 패킷을 재전송한다.



03. TCP 소켓을 기반으로 write함수와 read 함수가 호출되었을 때의 데이터 이동을 입력버퍼와 출력버퍼의 상태와 더불어 설명해 보자.

TCP 소켓에 존재하는 입출력 버퍼
TCP 소켓의 데이터 송수신에는 경계가 없다. , 서버가 한번의 write 함수 호출을 통해서 40바이트를 전송해도 클라이언트는 네 번의 read 함수 호출을 통해서 10바이트씩 데이터를 수신하는 것이 가능하다. 이러한 것이 가능하게 해 주는 것이 바로 버퍼이다
.
write 함수가 호출되는 순간 데이터는 출력버퍼로 이동을 하고, read 함수가 호출되는 순간 입력버퍼에 저장된 데이터를 읽어 들이게 된다
.

 

입출력 버퍼의 특성

Posted by Triany
2011. 7. 21. 18:01
01. TCP/IP 프로토콜 스택을 4개의 계층으로 구분해 보자. 그리고 TCP 소켓이 거치는 계층구조와 UDP 소켓이 거치는 계층구조의 차이점을 설명해보자.

                                        [TCP/IP 프로토콜 스택 _ 4계층 표현]



[TCP와 UDP 게층 ] 전송계층(Transport Layer)이라고도 함. IP계층에서 알려준 경로정보를 바탕으로 데이터의 실제 송.수신을 담당. IP의 상위계층에서 호스트 대 호스트의 데이터 송수신 방식을 약속.

TCP 역할 : TCP는 신뢰성있는 데이터의 전송을 담당. TCP가 데이터를 보낼때 기반이 되는 프로토콜이 IP이다. IP는 오로지 하나의 데이터 패킷(데이터 전송의 기본단위)이 전송되는 과정에만 중심을 두고 설계되었다. 이에 데이터를 주고받는 과정에서 TCP는 그 확인절차를 걸쳐서 신뢰성 없는 IP에 신뢰성을 부여한 프로토콜





02. TCP/IP 프로토콜 스택 중에서 LINK 계층과 IP 계층이 담당하는 역할이 무엇인지 설명해보자. 그리고 이 둘의 관계도 함께 설명해보자.

LINK 계층 : 물리적인 영역의 표준화에 대한 결과. 즉, 가장 기본이 되는 영역으로 LAN, WAN, MAN과 같은 네트워크 표준과 관련된 프로토콜을 정의하는 영역.
IP 계층 : 데이터 전송을 위한 경로 검색. 이 계층에서 사용하는 프로토콜이 IP



03. TCP/IP 프로토콜 스택을 4개의 계층(또는 7개의 계층)으로 나누는 이유는 무엇인가? 이를 개방형 시스템에 대한 설명과 함께 답해보자.
프로토콜을 계층화하여 얻게되는 장점이, 표준화 작업을 통한 '개방형 시스템(Open System)'의 설계.
TCP/IP 프로토콜 스택역시 개방형 시스템의 하나로, 라우터, 및 랜 카드 등이 제조사들이 LINK 계층의 표준에 따라 제조하기에, 어느 제조사의 제품이든 쉽게 교체가능(인터페이스, 컴포넌트 화 되어있는. 규격이 맞춰져 있는 장점.)


04. 클라이언트는 connect 함수호출을 통해서 서버로의 연결을 요청한다. 그렇다면 클라이언트는 서버가 어떠한 함수를 호출한 이후부터 connect 함수를 호출할 수 있는가?
listen(연경요청 대기상태) 함수가 호출되어야 클라이언트는 연결요청을 위하여 connect 함수를 호출할 수 있다.

05. 연결요청 대기 큐라는 것이 생성되는 순간이 언제이며, 이것이 어떠한 역할을 하는지 설명해보자. 그리고 accept 함수와의 관계도 함께 설명해보자.
 #include <sys/type.h>

int listen(int sock, int backlog);   //성공시 0, 실패시 -1반환
○sock : 연결요청 대기상태에 두고자 하는 소켓의 파일 디스크립터 전달, 이 함수의 인자로 전달된 디스크립터의 소켓이 서버 소켓(리스닝 소켓)이 된다.
○backlog : 연결요청 대기 큐(Queue)의 크기정보 전달, 5가 전달되면 큐의 크기가 5가 되어 클라이언트의 연결요청을 5개까지 대기시킬 수 있다.

listen 함수가 호출되면, 문지기의 역할을 하는 서버소켓이 만들어 지고, listen함수의 두번째 인자로 전달되는 정수의 크기에 해당하는 대기실이 만들어진다. 이 대기실을 가리켜 '연결 요청 대기 큐'라고 하며, 서버 소켓과 연결요청 대기 큐가 완전히 준비되어서 클라이언트의 연결요청을 받아들일 수 있는 상태를 가리켜 '연결요청 대기 상태'라 한다.


06. 클라이언트 프로그램에서 소켓에 주소정보를 할당하는 bind 함수호출이 불필요한 이유는 무엇인가? 그리고 bind함수를 호출하지 않았을 경우, 언제 어떠한 방식으로 IP주소와 PORT번호가 할당되는가?
네트워크를 통해서 데이터를 송수신하려면 IP와 PORT가 반드시 할당되어야 한다.
언제? connect 함수가 호출될 때,
어디서? 운영체제에서, 보다 정확히 표현하면 커널에서
어떻게? IP는 컴퓨터(호스트)에 할당된 IP로, PORT는 임의로 선택해서!!
: 즉, bind함수를 통하여 소켓에 IP와 PORT를 직접 할당하지 않아도 connect 함수 호출 시 자동으로 소켓에 IP와 PORT 가 할당된다. 따라서 클라이언트 프로그램을 구현할 때에는 bind함수를 명시적으로 호출할 필요가 없다.


07. Capter 01에서 구현한 예제 hello_server.c와 hello_server_win.c를 lterative 모델로 변경하고 제대로 변경이 되었는지 클라이언트와 함께 테스트해보자.
Iterative 서버 : 계속하여 들어오는 클라이언트의 연결 요청을 수락하기 위한 서버.
               ( 현 단계에서는 fork. 즉 프로세스와 스레드에 대한 고려 없이 그저 반복문으로 구현한다.)
Posted by Triany
2011. 7. 21. 17:05
01. IP주소 체계인 IPv4와 IPv6의 차이점은 무엇인가? 그리고 IPv6의 등장 배경은 어떻게 되는가?
IPv4(Internet Protocol version 4) 4바이트 주소체계
IPv6(Internet Protocol version 6) 16바이트 주소체계

IPv6는 2010년을 전후로 IP주소가 모두 고갈될 것으로 염려하여 만들어진 표준

02. 회사의 로컬 네트워크에 연결되어 있는 개인 컴퓨터에 데이터가 전송되는 과정을, IPv4의 네트워크 ID와 호스트 ID, 그리고 라우터의 관계를 기준으로 설명하여라.
네트워크 주소(네트워크 ID)만을 참조하여 라우터로 전송. 해당 네트워크(네트워크를 구성하는 라우터는)는 전송된 데이터의 호스트 주소(호스트ID)를 참조하여 개인 컴퓨터로ㅗ 데이터를 전송해 준다.



03. 소켓의 주소는 IP와 PORT 번호 두 가지로 구성된다. 그렇다면 IP가 필요한 이유는 무엇이고, PORT번호가 필요한 이유는 또  무엇인가? 다시 말해서, IP를 통해서 구분되는 대상은 무엇익고, PORT번호를 통해서 구분되는 대상은 또 무엇인가?
IP - 개인 컴퓨터에는 NIC(네트워크 인터페이스 카드)이라 불리는 데이터 송수신 장치가 하나씩 달려있는데, IP는 데이터를 NIC를 통해 컴퓨터 내부로 전송하는데 사용된다.
PORT번호 - 소켓의 구분에 활용됨


04.  IP주소의 클래스를 결정하는 방법을 설명하고, 이 근거로 다음 IP주소들이 속하는 클래스를 판단해 보자.
클래스 A의 첫 번째 바이트 범위     0 이상 127 이하
클래스 B의 첫 번째 바이트 범위  128 이상 191 이하
클래스 C의 첫 번째 바이트 범위  192 이상 223 이하

211.121.212.102 ( 클래스 C )
120.101.122.89  ( 클래스 A )
129.78.102.211  ( 클래스 B )



05. 컴퓨터는 라우터 또는 스위치라 불리는 물리적인 장치를 통해서 인터넷과 연결되다. 그렇다면 라우터  또는 스위치의 역할이 무엇인지 설명해 보자.
네트워크를 구성하려면 외부로부터 수신된 데이터를 호스트에 전달하고, 호스트가 전달하는 데이터를 외부로 송수신 해주는 물리적 장치가 필요한데, 이를 가리켜 라우터 또는 스위치라 한다.(라우터보다 기능적으로 작은 것을 가리켜 스위치라 부르는데, 사실상 이 둘은 같은 의미로 사용이 된다.)

06. '잘 알려진 PORT(Well-kown PORT)'는 무엇이며, 그 값의 범위는 어떻게 되는가? 그리고 잘 알려진 PORT중에서 대표적인 HTTP와 FTP의 PORT번호가 어떻게 되는지 조사해 보자.
0~ 1023 까지 Well-known PORT라 한다.
HTTP : 80
20, 21(FTP data, control) 
23(Telnet)


07. 소켓에 주소를 할당하는 bind 함수의 프로토타입은 다음과 같다.
  int bind(int sockfd, struct sockaddr * my addr, socklen_t addrlen);
 
 그런데 호출은 다음의 형태로 이뤄진다. 
 bind(serv_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr);

 여기서 serv_addr은 구조체 sockaddr_in 변수이다. 그렇다면 bind함수의 프로토타입과 달리 구조체 sockaddr_in의 변수를 사용하는 이유는 무엇인지 간단히 설명해 보자.



08. 빅 엔디안과 리틀 엔디안에 대해서 설명하고, 네트워크 바이트 순서가 무엇인지 그리고 이것이 필요한 이유는 무엇인지 설명해 보자. 

09. 빅 엔디안을 사용하는 컴퓨터에서 4바이트 정수 12를 리틀 엔디안을 사용하는 컴퓨터에게 전송하려 한다. 이때 데이터의 전송과정에서 발생하는 엔디안의 변환과정을 설명해 보자.


10. '루프백 주소(loopback address)'는 어떻게 표현되며, 의미하는 바가 무엇인가? 그리고 루프백 주소를 대상으로 데이터를 전송하면 어떠한 일이 벌어지는가? 
 
 
Posted by Triany
2011. 7. 21. 17:05
01. 프로토콜이란 무엇을 의미하는가? 그리고 데이터 송수신에 있어서 프로토콜을 상의한다는 것은 어떠한 의미가 있는가?
:컴퓨터 상호간의 대화에 필요한 통신규약. 즉 약속


02. 연결지향형 소켓인 TCP 소켓의 전송 특성 세가지를 나열하여라
-중간에 데이터가 소멸되지 않고 목적지로 전송
-전송 순서대로 데이터가 수신
-전송되는 데이터의 경계(Boundary)가 존재하지 않는다.
  => "데이터를 전송하는 컴퓨터가 세 번의 write 함수호출을 통해서 총 100바이트를 전송하였다. 그런데 데이터를 수신하는 컴퓨터는 한 번의 read 함수호출을 통해서 100바이트를 전부 수신하였다.
"신뢰성 있는 순차적인 바이트 기반의 연결지향 데이터 전송 방식의 소켓"
int tcp_socket=socket(PF_INET, SOCk_STREAM, IPPROTO_TCP);


03. 비연결지향형 소켓의 특성 서술.
- 전송된 순서에 상관없이 가장 빠른 전송을 지향
- 전송된 데이터는 손실의 우려가 있고, 파손의 우려가 있다.
- 전송되는 데이터의 경계(Boundary)가 존재한다.
- 한번에 전송할 수 있는 데이터의 크기가 제한된다.
"신뢰성과 순차적 데이터 전송을 보장하지 않는, 고속의 데이터 전송을 목적으로 하는 소켓"
int udp_socket=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);


04. 다음 유형의 데이터 송수신에 가장 적합한 타입의 소켓이 무엇인지 결정, 그렇게 결정을 하게 된 이유를 설명
 a. 서태지와 아이들의 실시간 라이브 방송 멀티미디어 데이터(UDP소켓) _ 약간의 데이터 손상보다 빠른 속도를 우선시 하므로
 b. 철수가 압축한 텍스트 파일의 전송 ( TCP소켓 ) - 압축파일은 조금이라도 데이터 손상시 압축해제시 에러 발생
 c. 인터넷 뱅킹을 이용하는 고객과 은행 사이에서의 데이터 송수신 ( TCP소켓 ) 데이터가 손실되면 안됨

05. 데이터의 경계(Boundary)가 존재하지 않는 소켓은 어떠한 타입의 소켓인가? 그리고 이러한 소켓은 데이터를 수신할 때 무엇을 주의해야 하는지 서술해보자.
TCP소켓 _ read함수와 write함수 호출 횟수에 큰 의미 없음 _ 단 read 함수 호출로 읽혀지는 데이터의 양보다 많은 데이터가 수신되면 버퍼가 꽉 찰 수 있다.


06. tcp_server.c와 tcp_client.c에서는 서버가 한번즤 write함수 호출을 통해서 전송한 문자열을 여러 차례의 read 함수호출을 통해서 읽어 들였다. 그럼 이번에는 서버가 여러 차례의 write함수 호출을 통해서(횟수는 여러분이 결정!) 전송한 문자열을 클라이언트에서 한번의 read 함수 호출을 통해서 읽어 들이는 형태로 예제를 변경해 보자. 단, 이를 위해서 클라이언트는 read 함수의 호출 시기를 다소 늦출 필요가 있다. 서버가 데이터를 모두 전송할 때까지 기다려야 하기 때문이다. 그럼 이를 위해서 리눅스와 윈도우 양쪽 모두에서 다음의 유형의 문장을 이용해서 read또는 recv함수의 호출시기를 늦추기로 하자.
  for(i=0; i<3000; i++)
     printf("Wait time %d \n", i);

 디렇게 CPU에게 불필요한 일을 시켜가면서 실행의 흐름을 지연시키는 것을 가리켜 'Busy Waiting'이라 하는데, 이를 적절히 활용하면 우리에게 필요한 만큼 함수의 호출시기를 늦출 수 있다.

Posted by Triany