[C/C++] 소켓 API

2023. 4. 6. 15:22C&C++

소켓 API 정리 <winsock2.h>

 

SOCKET socket(int af, int type, int protocol) : 소켓 생성

인자: af: AF_INET(IPv4), type: SOCK_STREAM(TCP), SOCK_DGRAM(UDP), protocol: 0(TCP,UDP)

반환: 소켓 생성

 

int closesocket(SOCKET s) : 소켓 닫기

인자: s: 닫을 소켓

반환: 성공: 0, 실패: SOCKET_ERROR

 

int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) : Winsock DLL 사용 시작

인자: wVersionRequested(버전.MAKEWORD(2,2)), lpWSAData(WSADATA 변수의 주소)

반환: 성공:0, 실패:오류코드

 

int WSACleanup() : WinSock 작업에 필요한 모든 리소스 해제

반환: 성공: 0, 실패: SOCKET_ERROR

 

struct sockaddr_in : 소켓 주소 구조체

{

short sin_family // AF_INET(IPv4)

unsigned short sin_port // 포트번호

struct in_addr sin_addr // IP 주소, sin_addr.s_addr : 32비트 주소를 담는 필드

char sin_zero[8]

}

 

u_short htons(u_short hostshort): 포트의 호스트 바이트 순서 > 네트워크 바이트 순서 변환

인자: hostshort: 호스트 바이트 순서 포트 번호

반환: 네트워크 바이트 순서의 포트 번호

 

u_short ntohs(u_short netshort): 포트의 네트워크 바이트 순서 > 호스트 바이트 순서 변환

인자: netshort: 네트워크 바이트 순서 포트 번호

반환:호스트 바이트 순서의 포트 번호

 

int inet_pton(int af, const char * src, void * dst)

const char * inet_ntop(int af, const void * src, char * dst, size_t size)

 

int bind(SOCKET sock, const struct sockaddr * addr, int addrlen): 지역 IP 주소, 포트번호를 바인딩(결정)한다.

반환: 성공:0, 실패: SOCKET_ERROR

 

int listen(SOCKET sock, int backlog): 소켓 TCP 상태를 LISTENING 상태로 바꾼다.

인자: backlog: backlog 큐의 길이(SOMAXCONN: 최대)

반환: 성공:0, 실패: SOCKET_ERROR

 

SOCKET accept(SOCKET sock, struct sockaddr * addr, int * addrlen): connect 요청한 클라이언트와 연결

인자: addr, addrlen으로 클라이언트의 정보를 갖고옴. 필요없다면 NULL 넣으면 된다.

반환: 성공:새로운 소켓, 실패: SOCKET_ERROR

 

int connect(SOCKET sock, const struct sockaddr * addr, int addrlen) : 서버에 연결 요청보낸다.

인자: addr, addrlen : 서버의 주소와 포트를 전달

반환: 성공:0, 실패: SOCKET_ERROR

 

int send(SOCKET sock, const char * buf, int len, int flags) : TCP프로토콜, 데이터를 송신버퍼로 보냄.

인자: buf, len: 보낼 데이터 시작 주소와 길이, flags: 0

반환: 성공: 보낸 바이트 수, 실패: SOCKET_ERROR

 

int recv(SOCKET sock, char * buf, int len, int flags): TCP프로토콜, 수신 버퍼의 데이터를 받는다.

인자: buf, len: 수신받을 버퍼와 받을 길이, flags: 0

반환: 성공: 받은 바이트 수, 연결 종료 시(FIN 수신시) 0 실패: SOCKET_ERROR 

 

int sendto(SOCKET sock, const char * buf, int len, int flags, const struct sockaddr * addr, int addrlen)

:UDP 프로토콜, 데이터를 송신버퍼로 보낸다.

인자: send의 인자와 동일 /  addr, addrlen : 수신처 정보 전달

반환: 성공: 보낸 바이트 수, 실패: SOCKET_ERROR

 

int recvfrom(SOCKET sock, char * buf, int len, int flags, struct sockaddr * addr, int * addrlen)

:UDP 프로토콜, 수신버퍼의 데이터를 받는다.

인자: recv 인자와 동일 / addr, addrlen: 송신처 정보를 가져옴.

반환: 성공: 받은 바이트 수, 실패: SOCKET_ERROR

 

int select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout)

인자: nfds: 0, 각각 read, write, except에 대한 fd_set, timeout(fd_set들에 아무것도 없을 경우 얼마만큼 block될건지 결정)

반환: 성공: 조건을 만족하는 소켓 개수 or 0(타임 아웃), 실패: SOCKET_ERROR

 

블로킹 소켓이라면, 수신 버퍼에 도착한 데이터가 없으면 block 된다.

sendto는 송신 버퍼에 자리가 없으면 block 된다.

 

소켓 옵션

setsockopt / getsockopt 함수로 소켓 옵션을 지정하고, 옵션 값을 얻어온다.

 

SO_BROADCAST : UDP 프로토콜에서 LAN 내부의 Broadcast를 활성화한다.

SO_KEEPALIVE: 연결되어있는 소켓들(ESTABLISHED 상태)을 대상으로 주기적으로 연결 여부를 확인한다.

상대 TCP가 정해진 시간에 응답하지 않는 경우, 몇번 더 패킷을 보내보고, 그래도 응답하지 않는다면 자동으로 소켓을 닫는다. 

SO_LINGER:

1. (l_onoff = 0, l_linger = 사용x) : 기본 closesocket 작동. closesocket은 곧바로 리턴하지만, 송신 버퍼의 데이터를 모두 백그라운드로 보내고 TCP 연결을 정상 종료한다.

2. (l_onoff = 1, l_linger = 0) : closesocket 시에 FIN 대신 RST를 보낸다.

3. (l_onoff = 1, l_linger = 일정시간>0): 일정 시간 동안 송신 버퍼 데이터를 모두 보내고 TCP 연결을 정상 종료한 후, closesocket 함수 리턴.

SO_REUSEADDR: 현재 사용 중인 IP 주소와 포트 번호를 재사용할 수 있게 한다.

 

TCP_NODELAY: 네이글 알고리즘을 비활성화한다. (송신 버퍼에 MSS 만큼 쌓이지 않아도 바로 보낸다.)

 

'C&C++' 카테고리의 다른 글

[C++] 모던 C++(C++11) 기초  (1) 2023.05.09
[C&C++] const 키워드  (0) 2023.04.25
[C++] 간단한 디자인패턴  (0) 2022.01.07
[C++] 템플릿  (0) 2022.01.07
[C++] 형 변환 연산  (0) 2022.01.07