2021-04-08-Thu-Study-KR

» studyKR

GEO

C

UDP Receive Socket

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

#define BUFF_SIZE 1024

int sock;
sock = sopcket(PF_INET, SOCK_DGRAM, 0); // TCP에서는 SOCK_STREAM
if(-1 == sock) {printf("socket creation failed"); exit(1);}
struct sockaddr_in sv_ad;
memset(&sv_ad, 0, sizeof(sv_ad));
sv_ad.sin_family = PF_INET;
    IPv4 protocol
sv_ad.sin_port = htons(4000);
    port number = 4000
sv_ad.sin_addr.s_addr = htonl(INADDR_ANY)
    //주소 지정, 실행되는 시스템마다 ip를 달리하기 위해, 고정 ip가 아닌 htonl(INADDR_ANY) 사용
struct sockaddr_in cl_ad;
int cl_ad_size;
    //송신측 주소 정보를 받기 위해 변수 설정
cl_ad_size = sizeof(cl_ad);
recvfrom(sock, buff_receive, buffer_size, 0, (struct sockaddr*)&cl_ad, &cl_ad_size) 
   // buff에 수신한 자료 저장
   // cl_ad에 송신측 주소 정보 저장
   // cl_ad를 이용해 송신한 측으로 자료 전송

sendto(sock, buff_send, strlen(buff_send)+1,0,(struct sockaddr*)&cl_ad,sizeof(cl_ad)); 
   // NULL도 포함 위해 +1

ex)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( void)
{
    int   sock;
    int   client_addr_size;

    struct sockaddr_in   server_addr;
    struct sockaddr_in   client_addr;

    char   buff_rcv[BUFF_SIZE+5];
    char   buff_snd[BUFF_SIZE+5];



    sock  = socket( PF_INET, SOCK_DGRAM, 0);
    
    if( -1 == sock)
    {
        printf( "socket 생성 실패n");
        exit( 1);
    }

    memset( &server_addr, 0, sizeof( server_addr));
    server_addr.sin_family     = AF_INET;
    server_addr.sin_port       = htons( 4000);
    server_addr.sin_addr.s_addr= htonl( INADDR_ANY);

    if( -1 == bind( sock, (struct sockaddr*)&server_addr, sizeof( server_addr) ) )
    {
        printf( "bind() 실행 에러n");
        exit( 1);
    }

    while( 1)
    {
        client_addr_size  = sizeof( client_addr);
        recvfrom( sock, buff_rcv, BUFF_SIZE, 0 , 
                        ( struct sockaddr*)&client_addr, &client_addr_size);
        printf( "receive: %sn", buff_rcv);
        
        sprintf( buff_snd, "%s%s", buff_rcv, buff_rcv);
        sendto( sock, buff_snd, strlen( buff_snd)+1, 0,  // +1: NULL까지 포함해서 전송
                        ( struct sockaddr*)&client_addr, sizeof( client_addr)); 
    }
}

UDP Send Socket

struct sockaddr_in sv_ad;
memset(&sv_ad, 0, sizeof(sv_ad));
sv_ad.sin_family = AF_INET;
sv_ad.sin_port = htons(4000);
sv_ad.sin_addr.s_addr = inet_addr("127.0.0.1")
sendto(sock, argv[1], strlen(argv[1])+1, 0, (struct sockaddr *)&sv_ad, sizeof(sv_ad));
  //  NULL도 포함 위해 +1
  //  sendto를 통해 커널에 소켓이 등록
struct sockaddr_in sv_ad;
int sv_ad_size
   // recvfrom()을 통해 송신 측의 정보를 받아 오기 위해 변수 선언
sv_ad_size = sizeof(sv_ad);
recvfrom(sock,buff_receive, BUFF_SIZE,0,(struct sockaddr*)*&sv_ad, &sv_ad_size);
//수신 자료가 있다면 자료는 buff에 저장

ex)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define  BUFF_SIZE   1024

int   main( int argc, char **argv)
{
   int   sock;
   int   server_addr_size;

   struct sockaddr_in   server_addr;

   char   buff_rcv[BUFF_SIZE+5];


   sock  = socket( PF_INET, SOCK_DGRAM, 0);
   
   if( -1 == sock)
   {
      printf( "socket 생성 실패n");
      exit( 1);
   }

   memset( &server_addr, 0, sizeof( server_addr));
   server_addr.sin_family     = AF_INET;
   server_addr.sin_port       = htons( 4000);
   server_addr.sin_addr.s_addr= inet_addr( "127.0.0.1");

   sendto( sock, argv[1], strlen( argv[1])+1, 0,    // +1: NULL까지 포함해서 전송
            ( struct sockaddr*)&server_addr, sizeof( server_addr));          

   server_addr_size  = sizeof( server_addr);
   recvfrom( sock, buff_rcv, BUFF_SIZE, 0 , 
            ( struct sockaddr*)&server_addr, &server_addr_size);
   printf( "receive: %sn", buff_rcv);
   close( sock);
   
   return 0;
}

Network

UDP는 TCP와 달리 read(), write()가 아닌, recvfrom()과 sendto()를 사용한다.
자유롭게 시스템 주소를 바꾸어 가면서 자료를 송수신 한다.
     <--> TCP는 한번 연결되면 연격뢴 시스템과 자료를 주고 받는다.
    recvfrom은 수신 data뿐만 아니라, 송신자 정보도 얻을 수 있다.
    sento는 전송할 목적지를 정할 수 있다.

bind()
    Socket에 주소를 할당하고 port 번호를 할당해서 커널에 등록
    커널에 등록하면 client로부터 지속적으로 자료를 수신
    socket에 주소와 port할당 시, sockaddr_in 구조체 사용

recvfrom()       
    자료 수신
sendto()
    데이터 전송

recvfrom()을 이용해 송신 측 주소 정보를 받음

main

int main(int argc, char*argv[])
argc
//    main()함수에 전달되는 데이터의 갯수
argv
 //   main() 함수에 전달되는 실제적인 데이터로 char형 포인터 배열로 구성이 되어있다.
 //   첫 번째 문자열은 프로그램의 실행 경로이다.

RL

MDP를 알때의 방법론

 1. 작은문제
 2. MDP를 알 때 = 보상 함수와 전이 확률 행렬을 안다. 
    (즉, 상태 S에서 액션 A를 실행하면 다음 상태가 어떻게 정해지는지, 보상이 어떻게 될지를 미리 알고 있다.)
    플래닝: 정책을 알 때 이를 이용해 정책을 개선해 나가는 과정
        PREDICTION 문제: 정책이 주어졌을 때, 각 상태의 밸류를 평가하는 문제
        CONTROL 문제: 최적의 정책함수를 찾는 문제
*테이블 기반 방법론: 주로 작은 문제이기 때문에 가능

밸류 평가: 반복적 정책 평가

테이블의 값들을 초기화한 후, 벨만 기대방정식을 반복적으로 사용하여 테이블에 적어 놓은 값들을 조금씩 업데이트해 나가는 방법론
    보상 함수와 전이 확률을 알고 있다. (보상 = -1 고정, 감마 = 1)
    1. 테이블 초기화
    2. 한 상태의 값을 업데이트
        벨만 기대 방정식: 현태 상태 S의 가치를 다음에 도달하게 되는 상태S'에 가치로 표현한 식
        종료 상태의 경우 가치가 '0'
    3. 모든 상태에 대해 2의 과정을 적용
    4. 2~3 과정 반복: 결국 실제 값에 수렴

최고의 정책 찾기: Policy iteration

정책 평가와 정책 개선을 번갈아 수행하며 정책이 수렴할 때까지 반복하는 방법론
    1. 임의의 정책으로 초기화
    2. 정책 평가: 반복적 정책 평가, 이 단계에서는 고정된 정책에 대해 각 상태의 밸류를 구한다.
        정책을 따랐을 때, 각 상태의 가치 평가이기 때문에, 정책 평가라고 부른다. 한번만 평가해도 optimal이 된다.
    3. 정책 개선: greedy 정책 생성
    4. 2~3 반복
    5. 수렴하는 곳이 바로 최적 정책, 최적 가치가 된다.

최고의 정책 찾기 - Value iteration

오로지 최적 정책이 만들어내는 최적 value 하나만 바라봄
테이블 기반 방법론
MDP를 모두 아는 상황에서 최적 밸류를 알면 최적 정책을 곧바로 얻을 수 있다.