소켓 프로그래밍

1. 소켓 생성

소켓을 생성할때는 socket() 함수를 사용한다.

socket() 함수의 반환타입은 int이다.

int socket(int af, int type, int protocol);

 

  - af : 주소 체계 (IPv4, IPv6)

  - type : 소켓 타입 (TCP, UDP)

  - protocol : 일반적으로 0 (자동 선택)

 

 

ex)

SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
    std::cout << "Socket creation failed" << std::endl;
    return 1;
}

 

  - SOCKET : typedef된 int타입

  - INVALID_SOCKET : 0외의 다른 값을 에러로 define. -1로 적어도 상관없음

 

 

2. 서버 소켓 바인딩 (bind)

서버 소켓은 bind() 함수를 사용해 특정 IP 주소와 포트에 바인딩된다.

int bind(SOCKET s, const struct sockaddr *name, int namelen);

 

 

  - s : 바인딩할 소켓

  - name : 사용할 서버 주소의 sockaddr 구조체 포인터

  - namelen : name 변수값의 길이

 

ex)

SOCKADDR_IN serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(7777);

if (bind(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
    std::cout << "Bind failed" << std::endl;
    return 1;
}

 

 

  - SOCKADDR_IN : sockaddr_in 구조체

  - sin_family : IPv4 / IPv6

  - sin_addr : 사용가능한 IP중 하나를 자동으로 사용

  - sin_port : 사용할 포트

 

 

3. 연결 대기 (Listen)

listen() 함수를 사용해 클라이언트의 연결을 기다린다.

int listen(SOCKET s, int backlog);

 

  - backlog : 대기 큐의 최대 길이

 

 

ex)

if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
    std::cout << "Listen failed" << std::endl;
    return 1;
}

 

  - SOMAXCONN : 자동으로 설정되는 연결 큐의 최대 길이

 

 

4. 연결 수락 (Accept)

accept() 함수를 사용해 클라이언트의 연결 요청을 수락한다.

int accept(SOCKET s, (SOCKADDR*)addr, int *addrlen);

 

  - addr : 연결된 클라이언트의 주소를 저장하기 위한 버퍼

 

 

ex)

SOCKADDR_IN clientAddr;
int addrLen = sizeof(clientAddr);
if (accept(sock, (SOCKADDR*)&clientAddr, &addrLen) == SOCKET_ERROR) {
    std::cout << "Accept failed" << std::endl;
    return 1;
}

 

 

5. 데이터 송수신 (Send / Recv)

데이터 송신은 send() 함수, 수신은 recv() 함수를 사용한다.

int send(SOCKET s, const char *buf, int len, int flags);
int recv(SOCKET s, char *buf, int len, int flags);

 

  - buf : 송수신할 데이터를 저장할 버퍼

  - len : buf 버퍼의 길이

  - flags : 함수의 동작에 영향을 주는 플래그. 일반적으로는 0

 

 

ex)

char recvBuffer[100] = { 0 };
int recvLen = recv(sock, recvBuffer, sizeof(recvBuffer), 0);
if (recvLen <= 0) {
    std::cout << "Receive failed" << std::endl;
    return 1;
}

char sendBuffer[100] = "Hello client!";
int sendResult = send(clientSocket, sendBuffer, strlen(sendBuffer), 0);
if (sendResult == SOCKET_ERROR) {
    std::cout << "Send failed" << std::endl;
    return 1;
}

 

 

6. 소켓 종료

소켓 사용이 끝나면  closesocket()을 사용하여 소켓을 닫는다.

 

int closesocket(SOCKET s);

 

 

ex)

closesocket(socket);

 

 

7. 에러 처리

WSAGetLastError() 함수를 통해 마지막 소켓 작업에 대한 오류 상태를 반환한다.

대부분의 소켓 함수는 실패 시 -1을 반환한다.

 

ex)

int errCode = WSAGetLastError();
std::cout << "ErrorCode : " << errCode << std::endl;

'학습 > C++ 소켓 프로그래밍' 카테고리의 다른 글

UDP 소켓 프로그래밍  (0) 2024.10.31
TCP 소켓 프로그래밍  (0) 2024.10.31
소켓 프로그래밍 기초  (0) 2024.10.29
네트워크 프로그래밍 기초  (0) 2024.10.22
소켓 프로그래밍 학습목차  (0) 2024.10.15