"UDP라고 다를 거 없다"
앞에서 배운 TCP 소켓 프로그래밍과 원리가 동일하다!
[TCP 소켓 프로그래밍]
• send( ) : 데이터 송신(SOCK_STREAM)
• recv( ) : 데이터 수신(SOCK_STREAM)
[UDP 소켓 프로그래밍]
• sendto( ) : 데이터 송신(SOCK_DGRAM)
• recvfrom( ) : 데이터 수신(SOCK_DGRAM)
※ UDP에서는 클라이언트 측에서 connect() 함수를 사용할 필요가 없다
UDP는 연결지향(connectionless) 프로토콜로, 데이터그램을 목적지로 바로 보내거나 받을 수 있다. 따라서 서버와의 "연결"을 설정할 필요가 없다. 대신, 데이터를 보내거나 받을 때마다 sendto()와 recvfrom() 함수에서 목적지 정보를 명시한다.
따라서 connect()는 TCP에서 연결을 설정하는 데 필수이지만, UDP에서는 선택적이다.
(UDP에서도 connect()를 호출할 수 있지만, 호출해도 물리적인 연결이 생성되지 않고 소켓에 기본 송신/수신 대상이 설정될 뿐이다.)
(server1.c)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORTNUM 9005
int main() {
char buf[256];
struct sockaddr_in sin, cli;
int sd, clientlen = sizeof(cli);
// 인터넷 소켓을 사용하는 소켓을 생성
// 통신 방식은 SOCK_ DGRAM 으로 지정해 UDP를 사용하도록 함
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
// 소켓 주소 구조체를 초기화하고 포트 번호와 서버의 주소를 설정
memset((char*)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORTNUM);
sin.sin_addr.s_addr = inet_addr("192.168.147.129");
// 위에서 생성한 소켓을 bind() 함수를 사용해 바로 위에서 설정한 IP 주소/포트 번호와 연결
if (bind(sd, (struct sockaddr*)&sin, sizeof(sin))) {
perror("bind");
exit(1);
}
// recvfrom() 함수를 호출해 클라이언트에서 오는 메시지를 받음
while (1) {
// recvfrom() 함수는 메시지를 보낸 클라이언트의 주소도 함께 알려주므로
// 이 주소를 사용해 클라이언트로 메시지를 보낼 수 있음
if ((recvfrom(sd, buf, 255, 0, (struct sockaddr*)&cli, &clientlen)) == -1) {
perror("recvfrom");
exit(1);
}
printf("** From Client : %s\n", buf);
// 클라이언트로 간단한 메시지를 전송, sendto() 함수에는 목적지 주소를 인자로 지정해야 함
strcpy(buf, "Hello Client");
if ((sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr*)&cli, sizeof(cli))) == -1) {
perror("sendto");
exit(1);
}
}
return 0;
}
(client1.c)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PORTNUM 9005
int main() {
int sd, n;
char buf[256];
struct sockaddr_in sin;
// 소켓을 생성 (TCP 기반 프로그램과 달리 connect() 함수를 호출하지 않음)
if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
// 서버의 포트 번호와 IP 주소를 소켓 주소 구조체에 설정
memset((char*)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORTNUM);
sin.sin_addr.s_addr = inet_addr("192.168.147.129");
// sendto() 함수를 호출해 메시지를 서버로 전송
strcpy(buf, "I am a client.");
if (sendto(sd, buf, strlen(buf) + 1, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1) {
perror("sendto");
exit(1);
}
// 서버에서 전송한 응답 메시지를 recvfrom() 함수로 읽어 출력
n = recvfrom(sd, buf, sizeof(buf), 0, NULL, NULL);
buf[n] = '\0';
printf("** From Server : %s\n", buf);
return 0;
}
// 실행 결과: 서버와 클라이언트가 메시지를 주고받았음을 알 수 있음
참고 및 출처: 시스템 프로그래밍 리눅스&유닉스(이종원)
'Computer Science > UNIX & Linux' 카테고리의 다른 글
[UNIX/Linux] ep11-3+) TCP 소켓 프로그래밍 실습 (0) | 2024.12.10 |
---|---|
[UNIX/Linux] ep11-3) TCP 소켓 프로그래밍 (0) | 2024.12.08 |
[UNIX/Linux] ep11-2+) 소켓 프로그래밍 함수 실습 (0) | 2024.12.05 |
[UNIX/Linux] ep11-2) 소켓 프로그래밍 함수 (0) | 2024.12.04 |
[UNIX/Linux] ep11-1+) 소켓 프로그래밍 기초 함수 실습 (3) | 2024.12.03 |