본문 바로가기
개발/윈도우

[Window]에코 서버/클라이언트 프로그램

by p_human 2020. 4. 2.

이전 글에 이어서 이번에는 윈도우 운영체제에서 실행 가능한 에코 서버/클라이언트의 코드를 공개하겠습니다. Iterative한 에코 서버/클라이언트에 대한 설명은 리눅스의 에코 서버/클라이언트를 설명할 때 했으니 넘어가겠습니다.

아래는 에코 서버/클라이언트 코드 입니다.

#include <cstdio>
#include <cstdlib>
#include <WS2tcpip.h>
#define BUF_SIZE 1024

void Error_Handling(const char* _Message);
int main(int argc, const char* argv[])
{
    if (argc != 2) {
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }

    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        Error_Handling("fail WinSock Library init!");

    SOCKET hServSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (hServSock == INVALID_SOCKET)
        Error_Handling("socket() error");

    SOCKADDR_IN ServAdr;
    ZeroMemory(&ServAdr, sizeof(ServAdr));
    ServAdr.sin_family = AF_INET;
    ServAdr.sin_port = htons(atoi(argv[1]));
    ServAdr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

    if (bind(hServSock, (const SOCKADDR*)&ServAdr, sizeof(ServAdr)) == SOCKET_ERROR)
        Error_Handling("bind() error!");

    int backLog = 2;
    if (listen(hServSock, backLog) == SOCKET_ERROR)
        Error_Handling("listen() error!");

    SOCKET hClntSock;
    SOCKADDR_IN ClntAdr;
    int ClntAdrSize = sizeof(ClntAdr);
    int strLen = 0;
    char message[BUF_SIZE];
    for (int i = 0; i < backLog; i++) {
        hClntSock = accept(hServSock, (SOCKADDR*)&ClntAdr, &ClntAdrSize);
        if (hClntSock == SOCKET_ERROR)
            Error_Handling("accept() error!");
        else
            printf("Connected Client %d\n", i + 1);
		
        while ((strLen = recv(hClntSock, message, BUF_SIZE, 0)) != 0)
            send(hClntSock, message, strLen, 0);

        closesocket(hClntSock);
    }
    closesocket(hServSock);
    WSACleanup();
    return 0;
}

void Error_Handling(const char* _Message) {
    fputs(_Message, stderr);
    fgetc(stdin);
    exit(1);
}

#include <cstdio>
#include <cstdlib>
#include <WS2tcpip.h>
#define BUF_SIZE 1024
void Error_Handling(const char* _Message);
int main(int argc, const char* argv[]) {
    if (argc != 3) {
        printf("Usage : %s <port> <IP>\n", argv[0]);
        exit(1);
    }
	
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        Error_Handling("fail WinSock library init!!");

    SOCKET hServSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (hServSocket == INVALID_SOCKET)
        Error_Handling("socket() error!");

    SOCKADDR_IN ServAdr;
    ZeroMemory(&ServAdr, sizeof(ServAdr));
    ServAdr.sin_family = AF_INET;
    ServAdr.sin_port = htons(atoi(argv[2]));
    if (inet_pton(AF_INET, argv[1], &ServAdr.sin_addr.S_un.S_addr) == -1)
        Error_Handling("inet_pton() error!");

    if (connect(hServSocket, (const SOCKADDR*)&ServAdr, sizeof(ServAdr)) == SOCKET_ERROR)
        Error_Handling("connect() error!");

    char message[BUF_SIZE];
    int strLen = 0;
    int recvLen = 0, recvCount = 0;
    while (true) {
        printf("Input Message (Q to quit): ");
        fgets(message, BUF_SIZE, stdin);

        if (!strcmp(message, "q\n") || !strcmp(message, "Q\n"))
            break;

        strLen = send(hServSocket, message, strlen(message), 0);
        while (recvLen < strLen) {
            recvCount = recv(hServSocket, &message[recvLen++], BUF_SIZE - 1, 0);
        if (recvCount == -1)
            Error_Handling("read() error!");
        recvLen += recvCount;
        }
        message[recvLen] = 0;
        printf("Message from server data : %s", message);
    }
    closesocket(hServSocket);
    WSACleanup();
    return 0;
}

void Error_Handling(const char* _Message) {
    fputs(_Message, stderr);
    fputc('\n', stderr);
    exit(1);
}

이걸로 윈도우기반 에코 서버/클라이언트에 대한 설명?을 마치겠습니다.

글 읽어주셔서 감사합니다.

'개발 > 윈도우' 카테고리의 다른 글

[Window] TCP 서버 / 클라이언트 구현  (0) 2020.04.01