6/28/2007

[Network] TCP 클라이언트 프로그램 작성시 사용되는 함수들

** TCP 클라이언트 프로그램 작성시 사용되는 함수들

* socket 함수 : 소켓 지정자 socket(인자 도메인, 소켓의 형태, 프로토콜 종류)

-> 해당 소켓을 생성하고 소켓의 디스크립션을 반환한다.

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol)

- 인자 도메인 : 통신 도메인을 지정하는 인자로서 네트워크의 종류라고 생각하면 된다. 네트워크에는 노벨 IPX, ATM, X.25, IPv6 그리고 TCP 클라이언트 프로그램에서 사용하려고 하는TCP/IP 네트워크 등이 있다.

* 리눅스에서 정의되어 있는 프로토콜 패밀리 목록

PF_UNSPEC
PF_UNIX : 유닉스 도메인 소켓
PF_LOCAL : PF_UNIX 소켓의 포직스 표현
PF_INET : 인터넷 프로토콜
PF_AX25 : 아마추어 라디오 AX.25
PF_IPX : 노벨 IPX
PF_APPLETALK : 애플토크 DDP
PF_NETROM : 아마추어 라디오 NET/ROM
PF_BRIDGE : 다중 프로토콜 브리지
PF_ATMPVC : ATM PVCs
PF_X25 : X.25 프로젝트를 위해 예약
PF_INET6 : IPv6 프로토콜
PF_ROSE : 아마추어 라디오 X.25 PLP
PF_DECnet : DECnet 프로젝트를 위해 예약
PF_NETBEUI : 802.2LLC 프로젝트를 위해 예약
PF_SECURITY : 보안 콜백 주소 패밀리
PF_KEY : 키 관리 API
PF_NETLINK : 4.4BSD 에뮬레이트
PF_ROUTE : 4.4BSD 에뮬레이트
PF_PACKET : 패킷 패밀리
PF_ASH : Ash
PF_ECONET : Acorn Econet
PF_ATMSVC : ATM SVCs
PF_SNA : 리눅스 SNA 프로젝트
PF_IRDA : 적외선(IrDA) 소켓
PF_PPPOX : PPPoX 소켓
PF_WANPIPE : Wanpipe API 소켓
PF_LLC : 리눅스 LLC
PF_BLUETOOTH : 블루투스 소켓

- 표준 문서에서는 도메인을 지정할 경우에는 프로토콜 패밀리(PF_)를 사용하고, 도메인 인자를 지정할 때는 주소 패밀리(AF_)를 사용하도록 권장하지만 서로 바꾸어 사용하더라도 같은 값이기 때문에 문제는 발생하지 않는다.

- 소켓의 형태 : 소켓의 연결 형식을 정의. SOCK_STREAM, SOCK_DGRAM, SOCK_RAW 가 있다.

- SOCK_STREAM : TCP/IP 인터넷 프로토콜에서 TCP를 통해서 전송되는 신뢰성 있는 연결을 의미한다. TCP는 핸드셰이크라는 과정을 통해서 데이터를 전송할 때마다 해당 데이터를 잘 받았다는 확인 패킷을 받는다. TCP는 데이터를 전송할 때마다 확인 패킷을 받고 확인 패킷이 일정주기 이상 들어오지 않으면 상대편 종단과의 연결을 종료한다. TCP는 신뢰성 있는 연결 때문에 채팅, 게임, 인터넷, 등의 신뢰성이 필요한 분야에서 많이 사용한다.

- SOCK_DGRAM : TCP/IP 인터넷 프로토콜에서 UDP를 통해서 전송하는 신뢰성이 없는 연결을 의미한다. UDP는 데이터를 인터넷을 전송한 후 상대편에게 데이터를 잘 도착했는지 확인하지 않는다. UDP는 데이터를 전송하고 그 데이터의 도착 여부를 확인하지 않기 때문에 신뢰성이 보장되지 않아도 되는 동영상이나 오디오 스트림 서비스, 속도에 민감한 프로토콜의 설계에서
많이 사용한다.

- SOCK_RAW : TCP/IP 인터넷 프로토콜의 헤더를 우리가 직접 만들어 주어야 하는 것을 의미한다. SOCK_STREAM이나 SOCK_DGRAM은 해당 인터넷 프로토콜에 맞추어서 TCP/IP 인터넷 프로토콜의 헤더를 운영체제에서 자동으로 만들어 주지만 SOCK_RAW의 경우는 이런 헤더를 우리가 직접 만들어 주어야 한다. 이런 연결 방식은 특별한 형식의 패킷을 만들어서 네트워크에 전송한다거나 자신에게 전송되는 패킷을 모두 캡처하는 용도로 사용할 수 있다. RAW 소켓을 이용한 예로, 상대방의 통신 연결 상태를 확인하는 Ping 프로그램을 들 수 있다.

- socket 함수는 인자 값을 받아 소켓을 생성한 후에 해당 소켓의 지정자를 반환한다. 그리고 오류가 발생한 경우에는 소켓 지정자에 0보다 값을 반환하고 소켓 생성에 성공한 경우에는 소켓에 할당된 번호인 소켓 지정자를 반환한다.


* 바이트 오더(Byte Order) : 데이터의 저장되는 방식에 따라서 데이터 순서가 바뀌는 것.

- 리틀 엔디안(Little Endian) : 메모리에 데이터를 저장할 때 하위 비트의 데이터를 먼저 저장하는 방식(인텔 펜티엄 PC)

- 빅 엔디안(Big Endian) : 메모리에 데이터를 저장할 때 상위 비트의 데이터를 먼저 저장하는 방식


* inet_addr 함수 : 이진 바이너리 형식의 IP 주소 inet_addr (문자 형식의 IP 주소)

-> 문자 형식의 IP 주소를 네트워크 바이트 오더를 적용한 이진 바이너리 코드로 바꾸어 반환한다.

#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
unsigned long int inet_addr (const char *p)


* htons 함수 : 네트워크 바이트 오더가 적용된 이진 바이너리 16비트 값 htons (16비트 변수값)

-> 16비트의 unsinged short형 숫자 값에 네트워크 바이트 오더를 적용한 후 반환한다.

#include <netinet/in.h>
uint16_t htons(uint16_t hostshort)


* connect 함수 : 리턴 값 connect (소켓 디스크립션, 서버의 IP 주소와 포트번호, 길이)

-> 소켓 연결을 시작한다. 생성된 소켓과 서버의 정보를 이용해서 해당 서버에 연결한 후 결과값을 리턴한다. 0이면 성공, -1이면 실패를 의미한다.

#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)


* read 함수 : 읽은 값의 길이 read (파일 디스크립터, 읽은 데이터를 저장할 버퍼, 읽을 데이터 최대 길이)

-> 지정된 파일 디스크립터에서 데이터를 읽어서 지정된 버퍼에 데이터를 넣은 후 읽은 데이터의 길이를 반환한다. 오류가 발생하면 -1을 반환한다.

-> 네트워크 프로그래밍에서 파일 디스크립터에 해당하는 것이 소켓 디스크립터다. 소켓 디스크립터는 socket 함수가 반환하는 소켓의 번호를 의미하며 우리는 이것을 소켓 지정자라 한다.

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count)


* close 함수 : 성공 여부 반환 close (파일 디스크립터)

-> close 함수는 파일 디스크립터를 닫는다. 닫힌 파일 디스크립터는 더 이상 참조되거나 사용될 수 없다. 닫기에 성공하면 0을 반환하고 오류가 발생하면 -1을 반환한다.

#include <unistd.h>
int close(int fd)