기록

240107 로컬 호스트 서버 연결해보기

hayo_su 2024. 1. 7. 20:31

 

서버에 대한 이해도가 필요하다고 느껴졌고,

 

이전에 만든 imgui 화면을 이용해 채팅 서버를 만들어보려고 한다.


서버

  1. 소켓 생성 socket()
  2. 포트 번호 바인딩 bind()
  3. 수신 대기 listen()
  4. 연결 수락 accept()
  5. 데이터 송수신 read()& write()
  6. 연결 종료 close()

클라이언트

  1. 소켓 생성 socket()
  2. 연결 요청 connect() - 포트번호 지정, IP 주소를 텍스트에서 바이너리 형식으로 변환
  3. 데이터 송수신 read() & write()
  4. 연결 종료 close()

 

위와 같은 순서로 개발할 예정이다.


1. GUI

사용자가 서버가 되어야하기 때문에 서버와 클라이언트 어떤것으로 접속할 지 선택한다.

 

    if(false == SelectAccess)
    {
        if (ImGui::Button("Server Host"))
        {
            OpenServer();
            SelectAccess = true;
        }

        if (ImGui::Button("Access Client"))
        {
            Connect();
            SelectAccess = true;
        }
    }

추후 변경 점

1차 변경점) 서버가 존재하면 클라이언트로 접속하고 서버가 존재하지 않으면 본인이 서버가 될 수 있도록 변경할 예정이다.

2차 변경점) 외부 서버를 생성하고 클라이언트 대화창이 생성될 수 있도록 할 예정이다.


2. 서버

void OpenServer()
{
    // 소켓 생성
    WSAData WsaData;

    int errorCode = WSAStartup(MAKEWORD(2, 2), &WsaData);
    if (SOCKET_ERROR == errorCode)
    {
        MsgAssert("socket Error");
        return;
    }

    SOCKADDR_IN Add;
    Add.sin_family = AF_INET; // ip4주소 체계를 쓰겠다.
    Add.sin_port = htons(Port); // 네트워크 통신에 유효한 에디안 방식으로 만들어준다.
    if (SOCKET_ERROR == inet_pton(AF_INET, "0.0.0.0", &Add.sin_addr))
    {
        return;
    }

    MySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == MySocket)
    {
        return;
    }

    // 포트번호 바인딩
    if (SOCKET_ERROR == bind(MySocket, (const sockaddr*)&Add, sizeof(SOCKADDR_IN)))
    {
        return;
    }

    // 수신대기
    if (SOCKET_ERROR == listen(MySocket, BackLog))
    {
        return;
    }


}

3. 클라이언트

bool Connect()
{
    // 내 프로그램이 네트워크를 사용할래요.
    WSAData WsaData;

    int errorCode = WSAStartup(MAKEWORD(2, 2), &WsaData);
    if (SOCKET_ERROR == errorCode)
    {
        MsgAssert("socket Error");
        return false;
    }

    MySocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == MySocket)
    {
        return false;
    }

    SOCKADDR_IN ClientAdd;

    ClientAdd.sin_family = AF_INET;
    ClientAdd.sin_port = htons(Port);

    // 로컬호스트 ip 내컴퓨터에 내가 접속하겠다.

    if (SOCKET_ERROR == inet_pton(AF_INET, IP.c_str(), &ClientAdd.sin_addr))
    {
        return false;
    }

    int Len = sizeof(SOCKADDR_IN);

    // 접속 시간을 초과했습니다.
    if (SOCKET_ERROR == connect(MySocket, (const sockaddr*)&ClientAdd, Len))
    {
        MsgAssert("커넥트에 실패했습니다.");
        return false;
    }
    return true;
}

visual studio 2022에서 ctrl +alt + p 단축키로 연결 창을 열 수 있다.

 


Accept부터 추가로 진행할 예정~