< TCP 서버 함수호출 순서 >
#include <sys/socket.h>
int socket(int domain, int type, int protocol); // 성공 시 fd, 실패 시 -1 반환
-> 소켓 생성
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen); // 성공 시 0, 실패 시 -1 반환
-> 소켓에 주소정보 할당
#include <sys/socket.h>
int listen(int sockfd, int backlog); // 성공 시 0, 실패 시 -1 반환
-> 연결요청 대기상태
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); // 성공 시 fd, 실패 시 -1 반환
-> 연결 허용
[sockaddr_in 구조체]
struct sockaddr_in
{
sa_family_t sin_family // 주소체계
uint16_t sin_port // 16비트 TCP/UDP PORT번호
struct in_addr sin_addr // 32비트 IP주소
char sin_zero[8] // 사용되지 않음
}
[in_addr 구조체]
struct in_addr
{
in_addr_t s_addr // 32비트 IPv4 인터넷 주소
}
< TCP 클라이언트 함수호출 순서 >
#include <sys/socket.h>
int connect(int sock, const struct sockaddr *servaddr, socklen_t addrlen); // 성공 시 fd, 실패 시 -1 반환
-> 연결 요청
/* 기타 변환 함수들 */
#include <arpa/inet.h>
in_addr_t inet_addr(const char *string); // 성공 시 빅 엔디언으로 변환된 32비트 정수값, 실패 시 INADDR_NONE 반환
-> 문자열을 정수형으로 변환
#include <arpa/inet.h>
int inet_aton(const char *string, struct in_addr *addr); // 성공 시 1, 실패 시 0 반환
-> 문자열을 정수형으로 반환하고 반환된 정보를 in_addr 구조체 변수에 저장
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr addr); // 성공 시 변환된 문자열의 주소값, 실패 시 -1 반환
-> 네트워크 바이트 순서로 정렬된 정수형 IP주소를 문자열의 형태로 변환
unsigned short htons(unsigned short); // short형 데이터를 호스트 바이트순서 -> 네트워크 바이트순서로 변환
unsigned short ntohs(unsinged short); // short형 데이터를 네트워크 바이트순서 -> 호스트 바이트순서로 변환
-> PORT번호 변환에 사용됨
unsigned long htonl(unsigned long); // long형 데이터를 호스트 바이트순서 -> 네트워크 바이트순서로 변환
unsigned long ntohl(unsigned long); // long형 데이터를 네트워크 바이트순서 -> 호스트 바이트순서로 변환
-> IP번호 변환에 사용됨
/* 연결 초기화 */
struct sockaddr_in addr;
char *server_ip = "127.0.0.1";
char *server_port = "9999";
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(server_ip); // INADDR_ANY 로 줄 시 소켓이 동작하는 컴퓨터의 IP주소를 자동으로 할당
addr.sin_port = htons(atoi(serv_port));
< 함수호출 관계 >
서버는 소켓 생성 이후에 bind, listen 함수의 연이은 호출을 통해 대기상태에 들어가고 클라이언트는 connect 함수호출을
통해 연결요청을 하게 된다. 특히 클라이언트는 서버소켓의 listen 함수호출 이후에 connect 함수호출이 가능하다는 사실
을 기억할 필요가 있다. 뿐만 아니라 클라이언트가 connect 함수를 호출하기에 앞서 서버가 accept 함수를 먼저 호출할
수 있다.