Super Kawaii Cute Cat Kaoani
본문 바로가기
💾 lecture/컴퓨터 네트워크

컴퓨터 네트워크 과제 echo software router 구현

by wonee1 2024. 6. 5.
728x90

 
 
 
echo software router 구현 
 
 
 
클라이언트는 0~4의 범위를 가지는 난수가 들어가는 응용 계층 헤더 필드 key를 패킷에 담아 라우터에게 보낸다. 이 때, 터미널에 해당 key 값을 출력해준다.
 
라우터는 해당 헤더 필드 값을 읽고, 자신의 포워딩 테이블을 참고하여, 해당하는 output port 번호를 port 필드에 넣은 뒤, 클라이언트에 되돌려준다.
 
- 서버에 구현해야하는 포워딩 테이블은 아래의 형태를 가지고 있다.
 

keyport
04
13
22
31
40

 
클라이언트는 패킷을 수신하면 port 필드 값을 출력해준다.
 
클라이언트는 총 5개의 패킷을 연달아서 보낸다. 즉, 답장도 5개가 돌아오고, 출력되는 port 값도 5개가 된다.
 
key값을 난수로 생성하므로 그 때마다 key와 port 값은 달라질 수 있다.
 


 
구현코드 
 
 
 
 
client

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <time.h>

struct packet {
    int key;
    int port;
};

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        return 1;
    }

    int port = atoi(argv[1]);

    // 소켓 생성 
    int clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (clientSocket == -1) {
        perror("Error creating socket");
        return 1;
    }

    const char* server_name = "localhost"; // 127.0.0.1

    struct sockaddr_in serverAddr; // Create socket structure
    memset(&serverAddr, 0, sizeof(serverAddr)); // Initialize memory space with zeros
    serverAddr.sin_family = AF_INET; // IPv4
    serverAddr.sin_port = htons(port);
    inet_pton(AF_INET, server_name, &serverAddr.sin_addr);  // Convert IP addr. to binary


    srand(time(NULL)); // seed를 현재 시간으로 설정하여 매번 다른 난수 생성

    struct packet request, reply;
    socklen_t serverAddrLen = sizeof(serverAddr);

    for (int i = 0; i < 5; ++i) {
        // 키 값을 난수로 생성한다. 
        request.key = rand() % 5;

        // 서버(라우터)에 키 값을 보낸다 
        printf("Sent request with key %d\n", request.key);
        sendto(clientSocket, &request, sizeof(request), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

        // 포트 번호를 서버로 부터 받는다 
        recvfrom(clientSocket, &reply, sizeof(reply), 0, (struct sockaddr*)&serverAddr, &serverAddrLen);
        printf("Received reply with port %d\n", reply.port);
    }

    
    close(clientSocket);

    return 0;
}

 
 
 
 
 
server 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

struct packet {
    int key;
    int port;
};

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        return 1;
    }

    int port = atoi(argv[1]);

    // 소켓 생성
    int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (serverSocket == -1) {
        perror("Error creating socket");
        return 1;
    }

    
    struct sockaddr_in serverAddr, clientAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(port);

    // 소켓 바인딩
    if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        perror("Error binding socket");
        close(serverSocket);
        return 1;
    }


    struct packet request, reply;
    socklen_t clientAddrLen = sizeof(clientAddr);

    for (int i = 0; i < 5; ++i) {
        // 클라이언트로 부터 키 값을 받는다 
        recvfrom(serverSocket, &request, sizeof(request), 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        

        // 포워딩 테이블 
        int forwardingTable[] = {4, 3, 2, 1, 0};
        reply.port = forwardingTable[request.key];

        // 포트 번호를 전송 
        sendto(serverSocket, &reply, sizeof(reply), 0, (struct sockaddr*)&clientAddr, clientAddrLen);
    }

    
    close(serverSocket);

    return 0;
}

 
 
 


☑️실행결과 
 
 

 

client  결과 

 
 
 
 

 
server 결과 

728x90