8 minute read

다른 PC에서 돌릴때

udp_comm.cpp

// udp_comm.cpp
#include <iostream>
#include <thread>
#include <cstring>
#include <arpa/inet.h>

#define PORT 5005
#define BUFFER_SIZE 1024

void receive_udp(int sockfd) {
    char buffer[BUFFER_SIZE];
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);

    while (true) {
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr*)&cliaddr, &len);
        buffer[n] = '\0';
        std::cout << "Received message: " << buffer << " from " << inet_ntoa(cliaddr.sin_addr) << ":" << ntohs(cliaddr.sin_port) << std::endl;
    }
}

void send_udp(int sockfd, const char* ip, int port) {
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    servaddr.sin_addr.s_addr = inet_addr(ip);

    while (true) {
        std::string message;
        std::getline(std::cin, message);

        sendto(sockfd, message.c_str(), message.size(), MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr));
    }
}

int main() {
    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Socket creation failed" << std::endl;
        return -1;
    }

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);

    if (bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
        std::cerr << "Bind failed" << std::endl;
        close(sockfd);
        return -1;
    }

    std::thread recv_thread(receive_udp, sockfd);
    std::thread send_thread(send_udp, sockfd, "192.168.1.101", PORT); // B 환경의 IP 주소

    recv_thread.join();
    send_thread.join();

    close(sockfd);
    return 0;
}

udp_comm.py

# udp_comm.py
import socket
import threading

class UdpComm:
    def __init__(self, local_ip, local_port, remote_ip, remote_port):
        self.local_ip = local_ip
        self.local_port = local_port
        self.remote_ip = remote_ip
        self.remote_port = remote_port
        
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((self.local_ip, self.local_port))

        self.recv_thread = threading.Thread(target=self.receive_udp)
        self.recv_thread.daemon = True
        self.recv_thread.start()

    def receive_udp(self):
        while True:
            data, addr = self.sock.recvfrom(1024)  # 버퍼 크기 1024 바이트
            self.on_receive(data.decode(), addr)

    def send_data(self, message):
        self.sock.sendto(message.encode(), (self.remote_ip, self.remote_port))

    def on_receive(self, message, addr):
        print(f"Received message: {message} from {addr}")

# IP 주소와 포트 설정
local_ip = "0.0.0.0"  # 모든 인터페이스에서 수신
local_port = 5005
remote_ip = "192.168.1.100"  # A 환경의 IP 주소
remote_port = 5005

# UdpComm 인스턴스 생성
udp_comm = UdpComm(local_ip, local_port, remote_ip, remote_port)

# 사용자 입력을 통한 데이터 송신
while True:
    message = input("Enter message: ")
    udp_comm.send_data(message)

동일 PC에서 개발

udp_comm.cpp

// udp_comm.cpp
#include <iostream>
#include <thread>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>  // close 함수 사용을 위한 헤더 파일

#define PORT 5006
#define BUFFER_SIZE 1024

void receive_udp(int sockfd) {
    char buffer[BUFFER_SIZE];
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);

    while (true) {
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr*)&cliaddr, &len);
        if (n < 0) {
            std::cerr << "recvfrom failed" << std::endl;
            continue;
        }
        buffer[n] = '\0';
        std::cout << "Received message: " << buffer << " from " << inet_ntoa(cliaddr.sin_addr) << ":" << ntohs(cliaddr.sin_port) << std::endl;
    }
}

void send_udp(int sockfd, const char* ip, int port) {
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    servaddr.sin_addr.s_addr = inet_addr(ip);

    while (true) {
        std::string message;
        std::getline(std::cin, message);

        int n = sendto(sockfd, message.c_str(), message.size(), MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr));
        if (n < 0) {
            std::cerr << "sendto failed" << std::endl;
        }
    }
}

int main() {
    int sockfd;
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Socket creation failed" << std::endl;
        return -1;
    }

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;  // 모든 네트워크 인터페이스에서 수신
    servaddr.sin_port = htons(PORT);

    if (bind(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
        std::cerr << "Bind failed: " << strerror(errno) << std::endl;
        close(sockfd);
        return -1;
    }

    std::thread recv_thread(receive_udp, sockfd);
    std::thread send_thread(send_udp, sockfd, "127.0.0.1", 5005); // B 환경의 IP 주소 및 포트

    recv_thread.join();
    send_thread.join();

    close(sockfd);
    return 0;
}

udp_comm.py

# udp_comm.py
import socket
import threading

class UdpComm:
    def __init__(self, local_ip, local_port, remote_ip, remote_port):
        self.local_ip = local_ip
        self.local_port = local_port
        self.remote_ip = remote_ip
        self.remote_port = remote_port
        
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((self.local_ip, self.local_port))

        self.recv_thread = threading.Thread(target=self.receive_udp)
        self.recv_thread.daemon = True
        self.recv_thread.start()

    def receive_udp(self):
        while True:
            data, addr = self.sock.recvfrom(1024)  # 버퍼 크기 1024 바이트
            self.on_receive(data.decode(), addr)

    def send_data(self, message):
        self.sock.sendto(message.encode(), (self.remote_ip, self.remote_port))

    def on_receive(self, message, addr):
        print(f"Received message: {message} from {addr}")

# IP 주소와 포트 설정
local_ip = "0.0.0.0"  # 모든 인터페이스에서 수신
local_port = 5005
remote_ip = "127.0.0.1"  # A 환경의 IP 주소
remote_port = 5006

# UdpComm 인스턴스 생성
udp_comm = UdpComm(local_ip, local_port, remote_ip, remote_port)

# 사용자 입력을 통한 데이터 송신
while True:
    message = input("Enter message: ")
    udp_comm.send_data(message)

build

g++ udp_comm.cpp -o udp_comm -lpthread

동일 PC에서 양방향 통신

•	C++ 프로그램: 포트 5005에서 수신하고 포트 5006으로 송신.
•	Python 프로그램: 포트 5006에서 수신하고 포트 5005으로 송신. ## udp_comm.cpp ```cpp // udp_comm.cpp #include <iostream> #include <thread> #include <cstring> #include <arpa/inet.h> #include <unistd.h>  // close 함수 사용을 위한 헤더 파일

#define RECV_PORT 5005 #define SEND_PORT 5006 #define BUFFER_SIZE 1024

void receive_udp(int sockfd) { char buffer[BUFFER_SIZE]; struct sockaddr_in cliaddr; socklen_t len = sizeof(cliaddr);

while (true) {
    int n = recvfrom(sockfd, buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr*)&cliaddr, &len);
    if (n < 0) {
        std::cerr << "recvfrom failed" << std::endl;
        continue;
    }
    buffer[n] = '\0';
    std::cout << "Received message: " << buffer << " from " << inet_ntoa(cliaddr.sin_addr) << ":" << ntohs(cliaddr.sin_port) << std::endl;
} }

void send_udp(int sockfd, const char* ip, int port) { struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
servaddr.sin_addr.s_addr = inet_addr(ip);

while (true) {
    std::string message;
    std::getline(std::cin, message);

    int n = sendto(sockfd, message.c_str(), message.size(), MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr));
    if (n < 0) {
        std::cerr << "sendto failed" << std::endl;
    }
} }

int main() { int recv_sockfd, send_sockfd;

// 수신 소켓 생성 및 바인드
if ((recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    std::cerr << "Receive socket creation failed" << std::endl;
    return -1;
}

struct sockaddr_in recvaddr;
memset(&recvaddr, 0, sizeof(recvaddr));
recvaddr.sin_family = AF_INET;
recvaddr.sin_addr.s_addr = INADDR_ANY;
recvaddr.sin_port = htons(RECV_PORT);

if (bind(recv_sockfd, (const struct sockaddr*)&recvaddr, sizeof(recvaddr)) < 0) {
    std::cerr << "Receive bind failed: " << strerror(errno) << std::endl;
    close(recv_sockfd);
    return -1;
}

// 송신 소켓 생성
if ((send_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    std::cerr << "Send socket creation failed" << std::endl;
    close(recv_sockfd);
    return -1;
}

std::thread recv_thread(receive_udp, recv_sockfd);
std::thread send_thread(send_udp, send_sockfd, "127.0.0.1", SEND_PORT);

recv_thread.join();
send_thread.join();

close(recv_sockfd);
close(send_sockfd);
return 0; } ``` ## udp_comm.py ```python # udp_comm.py import socket import threading

class UdpComm: def init(self, local_ip, local_port, remote_ip, remote_port): self.local_ip = local_ip self.local_port = local_port self.remote_ip = remote_ip self.remote_port = remote_port

    self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    self.sock.bind((self.local_ip, self.local_port))

    self.recv_thread = threading.Thread(target=self.receive_udp)
    self.recv_thread.daemon = True
    self.recv_thread.start()

def receive_udp(self):
    while True:
        data, addr = self.sock.recvfrom(1024)  # 버퍼 크기 1024 바이트
        self.on_receive(data.decode(), addr)

def send_data(self, message):
    self.sock.sendto(message.encode(), (self.remote_ip, self.remote_port))

def on_receive(self, message, addr):
    print(f"Received message: {message} from {addr}")

IP 주소와 포트 설정

local_ip = “0.0.0.0” # 모든 인터페이스에서 수신 local_port = 5006 remote_ip = “127.0.0.1” # A 환경의 IP 주소 remote_port = 5005

UdpComm 인스턴스 생성

udp_comm = UdpComm(local_ip, local_port, remote_ip, remote_port)

사용자 입력을 통한 데이터 송신

while True: message = input(“Enter message: “) udp_comm.send_data(message)



# A,B,C 통신
	•	A PC (C++): 포트 5001에서 수신하고 포트 5002로 송신
	•	B PC (C++): 포트 5002에서 수신하고 포트 5001으로 송신 및 포트 5003으로 송신
	•	C PC (Python): 포트 5003에서 수신하고 포트 5002로 송신
## A C++
```cpp
#include <iostream>
#include <thread>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>

#define A_RECV_PORT 5001
#define B_SEND_PORT 5002
#define BUFFER_SIZE 1024

void receive_udp(int sockfd) {
    char buffer[BUFFER_SIZE];
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);

    while (true) {
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr*)&cliaddr, &len);
        if (n < 0) {
            std::cerr << "recvfrom failed" << std::endl;
            continue;
        }
        buffer[n] = '\0';
        std::cout << "Received message: " << buffer << " from " << inet_ntoa(cliaddr.sin_addr) << ":" << ntohs(cliaddr.sin_port) << std::endl;
    }
}

void send_udp(int sockfd, const char* ip, int port) {
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    servaddr.sin_addr.s_addr = inet_addr(ip);

    while (true) {
        std::string message;
        std::getline(std::cin, message);

        int n = sendto(sockfd, message.c_str(), message.size(), MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr));
        if (n < 0) {
            std::cerr << "sendto failed" << std::endl;
        }
    }
}

int main() {
    int recv_sockfd, send_sockfd;

    // 수신 소켓 생성 및 바인드
    if ((recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Receive socket creation failed" << std::endl;
        return -1;
    }

    struct sockaddr_in recvaddr;
    memset(&recvaddr, 0, sizeof(recvaddr));
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_addr.s_addr = INADDR_ANY;
    recvaddr.sin_port = htons(A_RECV_PORT);

    if (bind(recv_sockfd, (const struct sockaddr*)&recvaddr, sizeof(recvaddr)) < 0) {
        std::cerr << "Receive bind failed: " << strerror(errno) << std::endl;
        close(recv_sockfd);
        return -1;
    }

    // 송신 소켓 생성
    if ((send_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Send socket creation failed" << std::endl;
        close(recv_sockfd);
        return -1;
    }

    std::thread recv_thread(receive_udp, recv_sockfd);
    std::thread send_thread(send_udp, send_sockfd, "B_PC_IP", B_SEND_PORT); // B PC의 IP 주소로 설정

    recv_thread.join();
    send_thread.join();

    close(recv_sockfd);
    close(send_sockfd);
    return 0;
}

B C++

#include <iostream>
#include <thread>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>

#define A_SEND_PORT 5001
#define B_RECV_PORT 5002
#define C_SEND_PORT 5003
#define BUFFER_SIZE 1024

void receive_udp(int sockfd) {
    char buffer[BUFFER_SIZE];
    struct sockaddr_in cliaddr;
    socklen_t len = sizeof(cliaddr);

    while (true) {
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr*)&cliaddr, &len);
        if (n < 0) {
            std::cerr << "recvfrom failed" << std::endl;
            continue;
        }
        buffer[n] = '\0';
        std::cout << "Received message: " << buffer << " from " << inet_ntoa(cliaddr.sin_addr) << ":" << ntohs(cliaddr.sin_port) << std::endl;
    }
}

void send_udp(int sockfd, const char* ip, int port) {
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    servaddr.sin_addr.s_addr = inet_addr(ip);

    while (true) {
        std::string message;
        std::getline(std::cin, message);

        int n = sendto(sockfd, message.c_str(), message.size(), MSG_CONFIRM, (const struct sockaddr*)&servaddr, sizeof(servaddr));
        if (n < 0) {
            std::cerr << "sendto failed" << std::endl;
        }
    }
}

int main() {
    int recv_sockfd, send_sockfd_a, send_sockfd_c;

    // 수신 소켓 생성 및 바인드
    if ((recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Receive socket creation failed" << std::endl;
        return -1;
    }

    struct sockaddr_in recvaddr;
    memset(&recvaddr, 0, sizeof(recvaddr));
    recvaddr.sin_family = AF_INET;
    recvaddr.sin_addr.s_addr = INADDR_ANY;
    recvaddr.sin_port = htons(B_RECV_PORT);

    if (bind(recv_sockfd, (const struct sockaddr*)&recvaddr, sizeof(recvaddr)) < 0) {
        std::cerr << "Receive bind failed: " << strerror(errno) << std::endl;
        close(recv_sockfd);
        return -1;
    }

    // 송신 소켓 생성 (A)
    if ((send_sockfd_a = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Send socket creation failed" << std::endl;
        close(recv_sockfd);
        return -1;
    }

    // 송신 소켓 생성 (C)
    if ((send_sockfd_c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        std::cerr << "Send socket creation failed" << std::endl;
        close(recv_sockfd);
        return -1;
    }

    std::thread recv_thread(receive_udp, recv_sockfd);
    std::thread send_thread_a(send_udp, send_sockfd_a, "A_PC_IP", A_SEND_PORT); // A PC의 IP 주소로 설정
    std::thread send_thread_c(send_udp, send_sockfd_c, "C_PC_IP", C_SEND_PORT); // C PC의 IP 주소로 설정

    recv_thread.join();
    send_thread_a.join();
    send_thread_c.join();

    close(recv_sockfd);
    close(send_sockfd_a);
    close(send_sockfd_c);
    return 0;
}

C python

import socket
import threading

class UdpComm:
    def __init__(self, local_ip, local_port, remote_ip, remote_port):
        self.local_ip = local_ip
        self.local_port = local_port
        self.remote_ip = remote_ip
        self.remote_port = remote_port
        
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((self.local_ip, self.local_port))

        self.recv_thread = threading.Thread(target=self.receive_udp)
        self.recv_thread.daemon = True
        self.recv_thread.start()

    def receive_udp(self):
        while True:
            data, addr = self.sock.recvfrom(1024)  # 버퍼 크기 1024 바이트
            self.on_receive(data.decode(), addr)

    def send_data(self, message):
        self.sock.sendto(message.encode(), (self.remote_ip, self.remote_port))

    def on_receive(self, message, addr):
        print(f"Received message: {message} from {addr}")

# IP 주소와 포트 설정
local_ip = "0.0.0.0"  # 모든 인터페이스에서 수신
local_port = 5003
remote_ip = "B_PC_IP"  # B PC의 IP 주소
remote_port = 5002

# UdpComm 인스턴스 생성
udp_comm = UdpComm(local_ip, local_port, remote_ip, remote_port)

# 사용자 입력을 통한 데이터 송신
while True:
    message = input("Enter message: ")
    udp_comm.send_data(message)

Tags:

Categories:

Updated: