728x90
echo software router 구현
클라이언트는 0~4의 범위를 가지는 난수가 들어가는 응용 계층 헤더 필드 key를 패킷에 담아 라우터에게 보낸다. 이 때, 터미널에 해당 key 값을 출력해준다.
라우터는 해당 헤더 필드 값을 읽고, 자신의 포워딩 테이블을 참고하여, 해당하는 output port 번호를 port 필드에 넣은 뒤, 클라이언트에 되돌려준다.
- 서버에 구현해야하는 포워딩 테이블은 아래의 형태를 가지고 있다.
key | port |
0 | 4 |
1 | 3 |
2 | 2 |
3 | 1 |
4 | 0 |
클라이언트는 패킷을 수신하면 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
'💾 lecture > 컴퓨터 네트워크' 카테고리의 다른 글
컴퓨터 네트워크 과제 rdt2.2 over UDP 구현 과제 (0) | 2024.06.05 |
---|---|
컴퓨터 네트워크 과제 UDP Echo server 구현 (0) | 2024.06.05 |
[NetWork] 네트워크 정리 (3) (0) | 2023.10.28 |
[NetWork] 네트워크 정리(2) (0) | 2023.10.28 |
[NetWork] 네트워크 정리 (1) (0) | 2023.10.27 |