본문 바로가기
컴퓨터 활용/리눅스 활용

[리눅스] socat 사용하기

by 호군 2012. 3. 5.
반응형
저는 socat을 사용하게된 이유는 udp를 사용하는 프로그램이 serial포트로 데이터를 전송해주는 방법이 필요했기 사용을 하게 됐습니다. 만약 이런게 없다면, 직접 프로그램을 작성하던가 udp 프로그램의 소스를 변경해야 했을 것입니다. 

socat은 의존성이 없는 두 채널 사이에서 양방향으로 데이터 전송을 중계한다. 각 채널은 파일, 파이프, 디바이스(serial line etc. or a pseudo terminal), 소켓(UNIX, IP4, IP6 - raw, UDP, TCP) 등 일 것이다. 
 
자세한 정보는 socat 사이트로 가서 확인하길 바랍니다.

1. socat 다운로드
설치하는 방법은 간단합니다.
os에 따라 yum이나 apt-get으로 설치하는 방법이 있지만, 소스코드를 다운로드하여 설치해보려고 합니다.
socat 사이트로 가서 socat x.x.x.x.tar.gz 압축 파일을 다운로드 합니다.

저는 socat-1.7.2.0.tar.gz 파일을 다운로드 했습니다. 다운로드한 압축 파일을 해제 합니다.

[dhna@localhost ~/Downloads]$ tar xfz socat-1.7.2.0.tar.gz



2. socat 빌드
make파일을 만들고, 소스를 컴파일하고 실행파일을 생성합니다.

[dhna@localhost ~/Downloads/socat-1.7.2.0]$ mkdir ~/socat
[dhna@localhost ~/Downloads/socat-1.7.2.0]$ ./configure
[dhna@localhost ~/Downloads/socat-1.7.2.0]$ make
[dhna@localhost ~/Downloads/socat-1.7.2.0]$ prefix=~/socat make install

prefix는 컴파일한 결과의 root 디렉토리를 설정하는 변수입니다.
만약 make install만 한다면, Makefile의 prefix변수에 정의된 /usr/local내에 bin, share, man 디렉토리에 설치됩니다. 


 3. socat 사용하기
socat 프로그램을 한번 실행해보자. 

[dhna@localhost ~/Downloads/socat-1.7.2.0/bin]$ socat udp-l:1235,fork udp:localhost:1234

서버의 포트는 1234번을 사용하고, 클라이언트는 1235번 포트로 데이터를 전송 할 것입니다. 


4. socat 테스트 하기
과연 이 socat 프로그램이 잘 동작할까?  udp 서버/클라이언트로 socat의 동작을 테스트 해보자.
[server.c]

// udp server source for socat test.
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>


int main(int argc, char **argv)

{

    int sockfd;

    int clilen;

    int state;


    struct sockaddr_in serveraddr, clientaddr;

    int read;

    char buffer[1024];

    char respBuffer[1024];


    clilen = sizeof(clientaddr);

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    if (sockfd < 0)

    {

        perror("socket error : ");

        exit(0);

    }


    bzero(&serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

    serveraddr.sin_port = htons(1234);


    state = bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    if (state == -1)

    {

        perror("bind error : ");

        exit(0);

    }


    printf("udp server reading...\n");

    while(1)

    {

        read = recvfrom(sockfd, (void *)buffer, sizeof(buffer)-1, 0, (struct sockaddr *)&clientaddr, &clilen);

        if (read < 0) {

            printf("read is %d\n", read);

            break;

        }

        buffer[read] = 0;

        printf("buffer=%s\n", buffer);

        

        strcpy(respBuffer, "response : ");

        strcpy(respBuffer+11, buffer);

        sendto(sockfd, (void *)respBuffer, read+strlen("response : "), 0, (struct sockaddr *)&clientaddr, clilen);

    }
    printf("udp server end...."); 

    close(sockfd);

}


위의 소스코드를 server.c파일에 복사합니다. 그리고 gcc로 컴파일 합니다.

[dhna@localhost ~/socat]$ mkdir test
[dhna@localhost ~/socat]$ cd test
[dhna@localhost ~/socat/test]$ vi server.c
[dhna@localhost ~/socat/test]$ gcc server.c -o server 



[client.c]

// udp client source for socat test
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>


int main(int argc, char **argv)

{

    int sockfd;

    int clilen;

    int state;

    char buffer[255];

    int sendCount;

    int bufferLen;


    struct sockaddr_in serveraddr;


    memset(buffer, 0x00, 255); 

    clilen = sizeof(serveraddr);

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);

    if (sockfd < 0)

    {

        perror("socket error : ");

        exit(0);

    }


    bzero(&serveraddr, sizeof(serveraddr));

    serveraddr.sin_family = AF_INET;

    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    serveraddr.sin_port = htons(1235);


    

    printf("udp client sending....\n");

    sendCount = 0;

    while(sendCount < 1000) {

        sprintf(buffer, "data count is %d", sendCount++);

        bufferLen = strlen(buffer);

        sendto(sockfd, (void *)buffer, bufferLen, 0, (struct sockaddr *)&serveraddr, clilen);
 

        bufferLen = recvfrom(sockfd, (void *)buffer, sizeof(buffer)-1, 0, NULL, NULL); 

        if (bufferLen < 0) {

            printf("read is %d\n", bufferLen);

            break;

        }

        buffer[bufferLen] = 0;

        printf("buffer=%s\n", buffer); 

        sleep(1);

    }

    printf("udp client end......\n");

    close(sockfd);

}


위의 소스코드를 client.c파일에 복사합니다. 그리고 gcc로 컴파일 합니다.

[dhna@localhost ~/socat/test]$ vi client.c
[dhna@localhost ~/socat/test]$ gcc client.c -o client 











 
반응형