티스토리 뷰



(1) socket(), 소켓 개설

PF_INET ==인터넷 프로토콜 사용하겠다는 뜻

SOCK_STREAM == TCP프로토콜 사용하겠다는 뜻


소켓 프로그래밍을 하기 위하여는 다섯 가지 요소 

사용할 트랜스포트 프로토콜(스트림 또는 데이터그램), 자신과 상대방의 IP 주소, 자신과 상대방의 포트번호가 지정돼야 함.


▶ socket()을 호출시에는 트랜스포트 프로토콜만을 지정하게 되는데 그림 2-8에 socket() 수행시 내부적으로 일어나는 동작을 나타냈다. 여기서 응용 프로그램이 프로토콜을 지정하여 socket()을 호출하면 소켓 인터페이스가 새로 생성된 소켓의 소켓번호를 리턴하는 것을 보여주고 있다.

▶ 한편 클라이언트는 자신이 사용할 포트번호를 명시적으로 지정할 필요가 없다. 즉, 클라이언트는 bind()를 호출할 필요가 없이 다음에 설명할 connect() 호출시 시스템(TCP/IP)이 임의의 포트번호를 지정해 준다.


(2) 연결할 서버의 소켓주소 구조체(sockaddr_in) 작성

▶ 클라이언트는 connect()를 호출하기 전에 서버의 주소를 지정한다.

▶ 아이피 주소와 포트번호를 포함하는 소켓주소 구조체 sockaddr_in를 작성하여야 한다.


(3) connect(), 서버와 연결요청

▶ (2)에서 만든 서버의 소켓주소 구조체를 사용하여 서버에게 접속요청을 하기 위하여 connect()를 호출한다.

int connect ( int s, const struct sockaddr *addr,int addrlen);

addrlen : 구조체의 크기

addr : 상대방 서버주소와 포트번호가 담긴 구조체

s : 서버와 연결시킬 클라이언트의 소켓번호


즉 클라이언트의 소켓에서 서버의 주소와 포트가 담긴 구조체를 이용해서 서버에 소켓 연결 요청을 하는 시스템콜


▶ connect()를 호출 성공시 0을 리턴한다. 실패시 -1리턴, 전역변수 errno에 에러코드 설정

▶ 클라이언트가 호출한 connect()가 성공적으로 연결되려면 서버에서 accept()를 호출해 두고 있어야 한다.


한편, connect() 시스템 콜 호출 중에 에러가 발생하였을 때는 바로 다시 connect()를 호출하지 말고 해당 소켓을 close()로 닫고, 새로운 소켓을 socket()으로 만든 후 사용하는 것이 안전하다.


클라이언트가 connect()시스템 콜을 하게되면 tcp 3-way hand shaking방법으로 서버와 연결을 설정하게 되므로 클라이언트에서는 cpu가 놀게 된다. 따라서 프로세스가 block상태로 변한다.


위 그림을 볼때 L5,L4,L3 통신 흐름에 초점을 맞춰 이해하기 바란다. 응용계층과 전송계층(L4)사이에 소켓이란게 존재하며 소켓번호와 소켓인터페이스를 통해 서버와 연결을 설정한다.


(4) 클라이언트가 서버와 연결되면 send(), recv() 또는 write(), read()를 사용하여 서버와 데이터를 송수신할 수 있다.



▶ send()와 write()는 스트림형(TCP) 소켓을 통하여 패킷을 송신하는 함수이다.

데이터를 전송할 소켓번호(s), 송신할 데이터 버퍼(buf), 전송할 데이터 크기(length)를 지정해야 하며 두 함수 모두 실제로 전송된 데이터 크기를 바이트 단위로 리턴한다.


▶ recv()와 read()는 스트림형(TCP) 소켓을 통하여 패킷을 수신하는 함수이며 

데이터를 수신할 소켓번호(s), 수신 버퍼(buf), 읽을 데이터 크기(length)를 지정해야 한다. 두 함수 모두 실제로 읽은 데이터 크기를 바이트 단위로 리턴한다.


▶ 스트림 소켓에서는 IP 패킷이 한 번에 전송할 수 있는 최대 데이터 크기보다 큰 데이터를 송신 버퍼에 저장하고 write()나 send()를 호출할 수 있다.

▶ 이때에는 전체 데이터가 IP 패킷 단위로 분할되어 전송되며 수신측에서는 패킷의 순서와 분실을 검사하고 필요하면 재전송을 요구하는데 이것이 바로 스트림(stream) 소켓을 사용하는 장점이기도 하다.

▶ 그러나 다음 절에서 설명할 UDP 소켓에서는 사용자가 전송을 요구한 데이터의 크기가 데이터그램 크기보다 크면 에러가 발생하거나 데이터그램 크기만큼만 한 번 전송되고 만다.


(5) close(), 소켓 닫기

▶소켓의 사용을 마치려면 해당 소켓번호(s)를 지정하여 다음과 같이 close()를 호출하여 소켓을 종료하여야 한다.

close(s);

▶ close()를 호출한 시점에 서버나 클라이언트의 송신 버퍼에 있으나 아직 전송하지 못한, 또는 네트웍내에서 전달중인 패킷들이 있을 수 있는데 close()는 디폴트로 이러한 패킷들을 모두 처리한 후에 소켓을 닫게 되어 있다.


댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함