본문

한줄한줄 살펴보는 Unix Socket Programming in C #1. UDP Client

#include <stdio.h>
//소켓 프로그래밍에 필요한 핵심헤더
#include <sys/socket.h>
//AF_INET, PF_INET에 대한 지원을 위한 헤더 
#include <netinet/in.h>
//htons, inet_addr 등을 위한 헤더 
#include <arpa/inet.h>

main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in servAddr;

    //AF_INET, PF_INET 모두 IPv4를 사용한다는것을 의미한다..이 둘은 동일한 값을 가리킨다(#define PF_INET AF_INET)
    //AF는 Address Family, PF는 Protocol Family를 지칭하며, socket()에서는 PF, sin_family에서는 AF가 보기 좋다.
    //SOCK_DIAGRAM 은 DIAGRAM Packet, 즉 UDP을 사용하겠다는 의미(UDP:User Diagram Packet)
    sockfd = socket(PF_INET, SOCK_DGRAM, 0);

    //memset()으로 해당 메모리값을 \0으로 채운다.
    //bzero((char *)&servAddr, sizeof(servAddr)); 로도 사용 가능하지만 memset의 사용을 권장한다.
    memset((char *)&servAddr, '\0', sizeof(servAddr));

    servAddr.sin_family = AF_INET;
    //inet_addr()은 char*을 in_addr_t로 변환해준다(Big Endian). inet_aton()의 사용을 권장하지만 이게 사용하기 편하다.
    servAddr.sin_addr.s_addr = inet_addr(argv[1]);
    //atoi는 character Array TO Integer로서 인자로 받아온 argv를 int로 변환하는 기능을 하며
    //htons는 Host TO Network Short로서, 네트워크는 Big Endian 방식을 사용하므로 이로 변환하는 기능을 한다..

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

    char msg[]="This is a test";
    //소켓 디스크립터(socketfd)를 사용하여  데이터(msg)를 flag없이(0) 서버(servAddr)에 보낸다..

    sendto(sockfd, (char *)&msg, sizeof(msg), 0, (struct sockaddr *)&servAddr, sizeof(servAddr));
   
    printf("Sent a message!\n");
    //소켓을 닫는다.
    close(sockfd);
}

위의 소스를 udpClient.c로 저장한 후 다음과같이 컴파일을 해준다.
gcc -o udpClient udpClient.c -lsocket -lnsl 
솔라리스 환경에서는 위와같이 실행하고 리눅스 환경에서는 -lsocket을제외하고 -lnsl만 적어준다.
(-lnsl = /usr/lib/libnsl(.so) 라이브러리를 로드하며, inet_addr()을 위해 사용된다)
이후 ./udpClient 10.212.217.74(서버 ip) 9999(서버 port) 와같은 방식으로 이를 실행하면 아래와 같은 결과를 볼 수 있다.
 

 

===================
참고자료 : 

struct sockaddr_in {
 u_char sin_len;
 u_char sin_family;
 u_short sin_port;
 struct in_addr sin_addr;
 char sin_zero[8];
};

struct in_addr {
 in_addr_t s_addr;
};

typedef uint32_t in_addr_t;


#define PF_INET AF_INET 등에 대해 알고싶다면
http://freebsd.active-venture.com/FreeBSD-srctree/newsrc/sys/socket.h.html

sockaddr_in, in_addr 원본. typedef uint32_t in_addr_t;은 두번째 페이지에 있다.
http://freebsd.active-venture.com/FreeBSD-srctree/newsrc/netinet/in.h.html#sockaddr_in
http://www.stanford.edu/~stinson/cs155/bin/in_h.txt

PF_INET, AF_INET의 차이점 ("프로토콜 체계를 설정하는 부분은 PF로 시작하는 상수를 사용하고, 주소 체계를 설정하는 부분은 AF로 시작하는 상수를 사용하는 것이 좋습니다")
http://blog.naver.com/PostView.nhn?blogId=l18400&logNo=60109296392

inet_addr(), 그리고 새로나온 버전인 inet_aton()
http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/inet_addr

02. htons htonl ntohs ntonl (little endian / big endian)
http://smeffect.tistory.com/entry/02-htons-htonl-ntohs-ntonl-little-endian-big-endian

sendto() 소켓으로 데이터를 전송(UDP 프로그래밍에 대한 전반적인 설명과 내용, 소스가 들어있다)
http://forum.falinux.com/zbxe/?document_srl=441113
 

댓글

Holic Spirit :: Tistory Edition

design by tokiidesu. powerd by kakao.