UDP sample code
다른 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)