UDP 소켓은 연결이라는 개념이 존재하지 않는다.

UDP의 데이터 송수신

- TCP는 1대 1의 연결을 필요로 하지만, UDP는 연결의 개념이 존재하지 않는다.

- 따라서 서버 소켓과 클라이언트 소켓의 구분이 없다. 

- 연결의 개념이 존재하지 않으므로, 하나의 소켓으로 둘이상의 영역과 데이터 송수신이 가능하다.


#include <sys/socket.h>


ssize_t sendto(int sock, void *buff, size_t nbyte, int flags, struct sockaddr *to, socklen_t addrlen);

-> 성공시 전송된 바이트 수, 실패 시 -1 반환 

- sock : 데이터 전송에 사용될 UDP 소켓의 파일 디스크립터를 인자로 전달.

- buff : 전송할 데이터를 저장하고 있는 버퍼의 주소 값 전달.

- nbytes : 전송할 데이터 크기를 바이트 단위로 전달.

- flags : 옵션 지정에 사용되는 매겨변수 , 지정할 옵션이 없다면 0 전달.

- to : 목적지 주소정보를 담고 있는 sockaddr 구조체 변수의 주소 값 전달.

- addrlen : 매개변수 to로 전달된 주소 값의 구조체 변수 크기 전달.


=> UDP 소켓은 연결의 개념이 있지 않으므로, 데이터를 전송 할 때마다 목적지에 대한 정보를 전달해야한다.    


#include <sys/socket.h>


ssize_t recvfrom(int sock, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);

->성공 시 수시한 바이트 수, 실패시 -1 반환 

- sock : 데이터 수신에 사용될 UDP 소켓의 파일 디스크립터를 인자로 전달.

- buff : 데이터 수신에 사용될 버퍼의 주소 값 전달. 

- nbytes : 수신할 최대 바이트 수 전달, 때문에 매개변수 buff가 가리키는 버퍼의 킉를 넘을 수 없다.

- flags : 옵션 지정에 사용되는 매겨변수, 지정할 옵션이 없다면 0 전달. 

- from : 발신지 정보를 채워 넣을 sockaddr 구조체 변수의 주소 값 전달.

- addrlen : 매개변수 from으로 전달된 주소 값의 구조체 변수의 크기 전달.  


uecho_server.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/socket.h>


#define BUF_SIZE 30

void error_handling(char *message);


int main(int argc, char *argv[])

{

int serv_sock;

char message[BUF_SIZE];

int str_len;

socklen_t clnt_adr_sz;

struct sockaddr_in serv_adr, clnt_adr;

if(argc!=2){

printf("Usage : %s <port>\n", argv[0]);

exit(1);

}

serv_sock=socket(PF_INET, SOCK_DGRAM, 0);

if(serv_sock==-1)

error_handling("UDP socket creation error");

memset(&serv_adr, 0, sizeof(serv_adr));

serv_adr.sin_family=AF_INET;

serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);

serv_adr.sin_port=htons(atoi(argv[1]));

if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)

error_handling("bind() error");


while(1) 

{

clnt_adr_sz=sizeof(clnt_adr);

str_len=recvfrom(serv_sock, message, BUF_SIZE, 0, 

(struct sockaddr*)&clnt_adr, &clnt_adr_sz);

sendto(serv_sock, message, str_len, 0, 

(struct sockaddr*)&clnt_adr, clnt_adr_sz);

}

close(serv_sock);

return 0;

}


void error_handling(char *message)

{

fputs(message, stderr);

fputc('\n', stderr);

exit(1);

}



uecho_client.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/socket.h>


#define BUF_SIZE 30

void error_handling(char *message);


int main(int argc, char *argv[])

{

int sock;

char message[BUF_SIZE];

int str_len;

socklen_t adr_sz;

struct sockaddr_in serv_adr, from_adr;

if(argc!=3){

printf("Usage : %s <IP> <port>\n", argv[0]);

exit(1);

}

sock=socket(PF_INET, SOCK_DGRAM, 0);   

if(sock==-1)

error_handling("socket() error");

memset(&serv_adr, 0, sizeof(serv_adr));

serv_adr.sin_family=AF_INET;

serv_adr.sin_addr.s_addr=inet_addr(argv[1]);

serv_adr.sin_port=htons(atoi(argv[2]));

while(1)

{

fputs("Insert message(q to quit): ", stdout);

fgets(message, sizeof(message), stdin);     

if(!strcmp(message,"q\n") || !strcmp(message,"Q\n"))

break;

sendto(sock, message, strlen(message), 0, 

(struct sockaddr*)&serv_adr, sizeof(serv_adr));

adr_sz=sizeof(from_adr);

str_len=recvfrom(sock, message, BUF_SIZE, 0, 

(struct sockaddr*)&from_adr, &adr_sz);


message[str_len]=0;

printf("Message from server: %s", message);

}

close(sock);

return 0;

}


void error_handling(char *message)

{

fputs(message, stderr);

fputc('\n', stderr);

exit(1);

}


uecho_con_client.c

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <sys/socket.h>


#define BUF_SIZE 30

void error_handling(char *message);


int main(int argc, char *argv[])

{

int sock;

char message[BUF_SIZE];

int str_len;

socklen_t adr_sz;

struct sockaddr_in serv_adr, from_adr;

if(argc!=3){

printf("Usage : %s <IP> <port>\n", argv[0]);

exit(1);

}

sock=socket(PF_INET, SOCK_DGRAM, 0);   

if(sock==-1)

error_handling("socket() error");

memset(&serv_adr, 0, sizeof(serv_adr));

serv_adr.sin_family=AF_INET;

serv_adr.sin_addr.s_addr=inet_addr(argv[1]);

serv_adr.sin_port=htons(atoi(argv[2]));

while(1)

{

fputs("Insert message(q to quit): ", stdout);

fgets(message, sizeof(message), stdin);     

if(!strcmp(message,"q\n") || !strcmp(message,"Q\n"))

break;

sendto(sock, message, strlen(message), 0, 

(struct sockaddr*)&serv_adr, sizeof(serv_adr));

adr_sz=sizeof(from_adr);

str_len=recvfrom(sock, message, BUF_SIZE, 0, 

(struct sockaddr*)&from_adr, &adr_sz);


message[str_len]=0;

printf("Message from server: %s", message);

}

close(sock);

return 0;

}


void error_handling(char *message)

{

fputs(message, stderr);

fputc('\n', stderr);

exit(1);

}


블로그 이미지

잉비니

,