본문 바로가기
개발 업무(코딩)-개발자였을때 썼던..

c언어 리눅스(linux) UDP 예제

by 주용사 2023. 1. 8.
728x90

server.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 9999

typedef struct {
        int a;
        char b[10];
}Form;
//server.c
int main(void){
        int sock;
        struct sockaddr_in addr, client_addr;
        int addr_len;

        Form formdata; // 주고 받을 데이터

        if((sock = socket(AF_INET, SOCK_DGRAM, 0)) <0) // socket 생성
        {
                perror("socket ");
                return 1;
        }

        memset(&addr, 0x00, sizeof(addr));
        addr.sin_family = AF_INET;                      // socket초기화 초기화
        addr.sin_addr.s_addr = htonl(INADDR_ANY);       // 0.0.0.0 ??
        addr.sin_port = htons(PORT);

        if(bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0){ // ip주소와 포트부여
                perror("bind ");
                return 1;
        }

        printf("my ip : %s, waiting for messages\n", inet_ntoa(addr.sin_addr)); // client에서 받는게 없으면 이것만 출력하고 대기중 일것이다.

        addr_len = sizeof(client_addr);

        int check_len;
        if((check_len = recvfrom(sock, &formdata, sizeof(formdata), 0, (struct sockaddr *)&client_addr, &addr_len)) < 0) // client의 데이터 수신
        {
                perror("recvfrom ");
                return 1;
        }

        printf("ip : %s\n", inet_ntoa(client_addr.sin_addr)); // client의 ip주소를 알 수 있고
        printf("received data ; %d %s\n", formdata.a, formdata.b); // client에서 받은 data를 알 수 있다.

        sendto(sock, &formdata, sizeof(formdata), 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); // client에게 수신된 데이터를 전송

        close(sock); // 종료

        return 0;

}

client.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 9999

typedef struct {
        int a;
        char b[10];
}Form;

//client.c
int main(void){
        int sock;
        struct sockaddr_in target_addr;
        int addr_len;

        Form formdata;

        formdata.a = 1;
        memcpy(formdata.b, "test", sizeof(formdata.b));

        if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) // socket 생성
        {
                perror("socket ");
                return 1;
        }

        memset(&target_addr, 0x00, sizeof(target_addr));
        target_addr.sin_family = AF_INET;                       // socket 초기화
        target_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
        target_addr.sin_port = htons(PORT);

        addr_len = sizeof(target_addr);

        sendto(sock, &formdata, sizeof(formdata), 0, (struct sockaddr*)&target_addr, addr_len); // server로 데이터 전송

        int check_len = 0;
        if((check_len = recvfrom(sock, &formdata, sizeof(formdata), 0, (struct sockaddr *)&target_addr, &addr_len)) < 0) // server로부터 데이터 수신
        {
                perror("recvfrom ");
                return 1;
        }

        printf("ip : %s\n", inet_ntoa(target_addr.sin_addr));
        printf("received data : %d %s\n", formdata.a, formdata.b); // 받은 데이터 출력

        close(sock); // socket 종료

        return 0;
}

 

https://nroses-taek.tistory.com/95

https://recipes4dev.tistory.com/153



그외 설명

bind를 사용하는 이유는 포트를 지정해주기 위함이다. 그것을 제외하면 운영체제에서 알아서 할당해준다​

유니캐스팅(unicasting)

가장 흔한 형태로, 두 애플리케이션이 통신하는 모델

 


브로드캐스팅(broadcasting)

한 네트워크에 속한 모든 개체와 통신하는 모델



멀티캐스팅(multicasting)

하나 또는 여러 네트워크에 속한 선별된 개체와 통신하는 모델이다. 브로드캐스팅은 멀티캐스팅의 특수한 경우에 속한다.

728x90