회원가입 ID/PW 찾기

1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.

콘텐츠 수 33
판매자 행복하면 판매 납포인트 무료 평점 0점 / 총 0명 참여
지금 학원에서 소켓 프로그래밍을 하고 잇는데...

멀티 메신저 프로그램을 만들려고 해서..

자료를 찾앗는데.. 간단하게 소켓 프로그래밍에서 쓰는 함수가

정리 된 것이 잇어서.. 이렇게 올려요^^;; ㅋㅋ

포인트 없는 분들을 위해.. 그냥.. 글로.. ㅋㅋㅋ

================================================================================================================


1. 소켓이란 무엇인가?
소켓은 한 시스템이나 네트워크 상에서 통신을 가능케 해주는 통신 인터페이스이다.
소켓은 버클리 유닉스 버전에 의해 소개되었다. 소켓을 사용하면 운영체제의 종류에
관계 없이 서버/클라이언트 환경을 구축할수있다.

2. 소켓 사용하기
소켓을 사용하기 위해서는 소켓 어드레스 정보가 담긴 구조체를 사용해야 한다.
로컬 시스템에서 사용하기위한 소켓은 sys/un.h 에 정의된 sockaddr_un 을 사용해야
한다.

struct sockaddr_un
    sa_family_t    sun_family;    /* 소켓 도메인(AF_UNIX) */
    char        sun_path[];    /* 어드레스 파일 경로   */
;

네트워크에서 사용하기 위한 소켓은 netinet/in.h 의 sockaddr_in 을 사용한다.

struct sockaddr_in
    short int          sin_family;  /* 소켓 도메인(AF_INET) */
    unsigned short int sin_port;    /* 포트 번호            */
    struct in_addr     sin_addr;    /* 인터넷 주소(IP)      */
    unsigned char      sin_zero[8]; /* sockaddr를 위한 변수 */
;

마지막의 sin_zero 는 실제적으로 데이터를 보내는데 사용되는 데이터 타입인
sockaddr 구조체와 크기를 같게하기 위한 변수이다. 이것은 0으로 채워야 한다.

▶ socket() - 소켓 생성
#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);

domain은 소켓 도메인(소켓종류)인데 AF_UNIX 나 AF_INET 이 될수있다. type 은 소켓
타입으로써 TCP를 사용하여 신뢰된 통신을 하기위한 SOCK_STREAM, UDP를 사용하는
SOCK_DGRAM 이 있다. protocol은 기본적으로 0으로 해준다.

socket 함수는 소켓을 생성하여 성공하면 새로운 소켓 기술자를, 실패하면 -1를 반환
한다.

▶ bind() - 소켓 어드레스 할당
#include <sys/socket.h>

int bind(int socket, const struct sockaddr *address, size_t address_len);

bind는 address에 담겨있는 어드레스를 socket 소켓에 할당한다. 인터넷 개념과 함께
말하자면 소켓을 로컬시스템의 포트에 연결하는 작업이다. address_len 은 address의
크기이다. bind는 어드레스를 할당하여 성공하면 0을 반환하고, 실패하면 -1을 반환
하고 errno를 셋팅한다.

▶ listen() - 소켓 큐 생성
#include <sys/socket.h>

int listen(int socket, int backlog);

listen 함수는 소켓을 위한 backlog 크기의 큐를 생성해 준다. 이 큐는 socket 과
관련된 포트에 접속하는 클라이언트들이 대기하는 하며, 후에 accept 를 사용하여
클라이언트와 통신할수 있다.

listen은 큐를 생성하여 성공할경우 0을 반환하고, 실패하면 -1를 반환하고 errno를
셋팅한다.

▶ accept() - 접속 받아들이기
#include <sys/socket.h>

int accept(int socket, struct sockaddr *address, size_t *address_len);

accept 함수는 socket과 관련된 큐에서 대기하고 있는 클라이언트와 통신할수 있도록
새로운 소켓 기술자를 반환한다. 클라이언트의 정보는 address 가 가르키는 sockaddr
구조체에 저장된다. address_len은 address의 길이를 지정한다. 이 accept는 소켓의
큐에 접속되어있는 클라이언트가 없다면, 클라이언트가 접속을 수행할때까지 대기
(방지) 될것이다. 함수는 성공하면 새로운 기술자를 반환하고 실패하면 -1를 반환한다.

▶ connect() - 접속하기
#include <sys/socket.h>

int connect(int socket, const struct sockaddr *address, size_t address_len);

connect 함수는 socket 을 address가 가르키는 주소에 접속 시킨다. address_len은
address의 크기이다. connect로 접속되고 나면 서버/클라이언트 관계가 형성되고
read, write 또는 send, recv 등으로 데이터를 주고 받을수 있다.
connect 함수는 성공하면 0을 반환하고 실패하면 -1를 반환한다.

▶ 소켓 닫기
소켓을 닫기 위해서는 일반 파일 기술자를 닫는 close 함수를 사용하면 된다.
close는 소켓이 전송되지 않는 데이터를 가지거나 아직 접속이 닫혀있지 않은
클라이언트가 있다면 방지된다. 소켓을 닫는 함수에는 shutdown 이라는 함수가 있다.

#include <unistd.h>

int shutdown(int sockfd, int how);

how에는 닫는 방법이 들어간다.

0 - 더이상의 수신 금지
1 - 더이상의 송신 금지
2 - 더이상의 송수신 금지(close()와 같은 경우)

shutdown은 에러가 나면 -1를 반환한다.

▶ 호스트와 네트워크 바이트 순서
소켓을 사용하는 컴퓨터는 여러가지가 있다. 그 시스템 중에는 메모리에 1-2-3-4
순으로 저장하는 시스템이 있지만, 4-3-2-1 방식으로 저장하는 시스템이 있다. 서버와
클라이언와 통신을 하기위해서는 서버의 같은 포트를 사용하여 통신을 해야 하는데
서버와 클라이언트의 바이트 순서가 달르게 되면 서버 소켓에서는 1574가 주어지지만
클라이언트에서 1574 포트를 접속하려할때 바이트 순서가 달라 9734 포트로 접속
할수도 있다. 이런 사태를 방지하기 위해 소켓에서는 네트워크 바이트 순서와 호스트
바이트 순서를 서로 변환 시킬수있는 함수를 지원한다. 다음은 변환 함수들이다

#include <netinet/in.h>

unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

함수는 함수이름 그대로 해석하면 된다

htons()--"Host to Network Short"
htonl()--"Host to Network Long"
ntohs()--"Network to Host Short"
ntohl()--"Network to Host Long"

서버에 접속하거나 대기하려 할때는 sockaddr_in 구조체의 주소 멤버에 htonl로
호스트 바이트 순서에서 네트워크 바이트 순서로 바꾼 주소값을 넣고, sin_port에는
htons로 변환한 포트 값을 넣으면 될것이다. 또, 네트워크 순서로 변환되어져 있는
값은 ntohs나 ntohl 로 호스트 바이트 순서로 변환하면 될것이다.

▶ 네트워크 정보(IP, 포트, 서비스)
점으로 구성된 아이피를 호스트/네트워크 바이트 순서로 바꾸기 위해서 다음 함수를
사용한다.

#include <arpa/inet.h>

unsigned long inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);

inet_addr 함수는 점으로 이루어진 아이피 문자열을 unsigned long(NBO)로 변환
해준다. inet_ntoa 함수는 그 반대로 NBO로 이루어진 아이피를 아스키 형식의 문자열로
해준다. 

IP 어드레스에 대한 정보를 알기 위해서는 다음과 같은 함수를 사용한다.

#include <netdb.h>

struct hostent *gethostbyaddr(const void *addr, size_t len, int type);
struct hostent *gethostbyname(const char *name);

위 두 함수로 부터 반환되는 hostent 구조체는 다음과 같다.

struct hostent
    char *h_name;        /* 호스트의 공식적인 이름    */
    char **h_aliases;    /* 호스트의 별명으로서 NULL 로 끝맺음된다 */
    int h_addrtype;        /* 주소의 종류, 보통 AF_INET */
    int h_length;        /* 주소의 바이트 수          */
    char **h_addr_list;    /* 0으로 끝나는 네트워크 주소들, NBO 구성 */
;

#define h_addr  h_addr_list[0]    /* h_addr_list 속의 첫번째 주소 */

로컬 시스템의 호스트 네임을 알아보기 위해서는 gethostname 함수를 사용한다.

#include <unistd.h>

int gethostname(char *name, int namelength);

gethostname은 namelength 길이의 호스트 네임을 name이 가르키는 공간에 넣는다.
성공하면 0을 반환하고, 실패하면 -1를 반환한다.

때로는 몇가지 서비스에 대한 정보를 알아보아야 할때도 있을 것이다.

#include <netdb.h>

struct servent *getservbyname(const char *name, const char *proto);
struct servent *getsevbyport(int port, const char *proto);

proto는 SOCK_STREAM 를 위한 tcp나 SOCK_DGRAM 을 위한 udp가 될수있다. 두번째
함수의 port 는 NBO이어야 한다. 두 함수에서 반환되는 정보를 갖는 servent
구조체는 다음 멤버를 가진다.

struct servent
    char *s_name;        /* 서비스 이름 */
    char **s_aliases;    /* 별칭의 목록 (선택적인 이름) */
    int s_port;        /* IP 포트 번호 */
    char *s_proto;        /* 일반적으로 "tcp"나 "udp"인 서비스 형태 */
;

▶ select() - 동시에 파일 기술자 검사하기
select 함수는 동시에 여러개의 파일 기술자를 읽기, 쓰기 행동이 있는지 알아볼수
있다. 또, 그 파일 기술자에서 읽을수 잇는 데이터나 쓸 데이터가 있을때까지
프로그램이 방지 되게 해준다.

#include <sys/types.h>
#include <sys/time.h>

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds,
    struct timeval *timeout);

nfds는 테스트할 파일기술자의 숫자인데, 보통 테스트할 최대 파일 기술자 +1 이다.
readfds 는 읽을 데이터가 있는지 테스트할 파일기술자 모음이고, writefds 는
쓸수 있는지, errrorfds는 에러조건을 가지는지 테스트할 파일 기술자 모음
이다. 그리고 마지막 timeout는 timeval 구조체에 대한 포인터 인데, select는
이 timeval 시간 만큼 파일 기술자에 대해 어떠한 행동이 이루어 질때까지 기다릴
것이다. select 함수는 파일 기술자 모음에 있는 파일 기술자중에 어떠한 기술자가
읽기나, 쓰기나, 에러를 가진다면 그 기술자가 변경되었음을 가르키도록 변경하고
리턴한다. 성공하면 파일기술자 모음의 전체 갯수를 반환하고 실패하면 -1를 반환한다.
또, timeout 동안 기달려도 파일기술자들에게 아무 반응이 없다면 0을 반환한다.

timeval 구조체는 다음 멤버를 가진다.

#include <sys/types.h>

struct timeval
    time_t    tv_sec;     /* 초 단위 */
    long    tv_usec; /* 밀리 초 단위 */
;

파일 기술자 모음에 파일기술자를 추가하거나 지우거나 반응이 있는지 검사하기 위해
다음 매크로들을 사용한다.

#include <sys/types.h>
#include <sys/time.h>

void FD_ZERO(fd_set *fdset);  /* 파일 기술자 모음을 0으로 초기화 한다  */
void FD_CLR(int fd, fd_set *fdset);  /* fdset 파일기술자 모음에서 fd를 지운다 */
void FD_SET(int fd, fd_set *fdset);  /* fdset 파일기술자 모음에 fd를 추가한다 */
int FD_ISSET(int fd, fd_set *fdset);  /* fd가 fdset 파일기술자 모음의 요소라면
                    0이 아닌값을 반환한다 */

파일기술자가 읽기/쓰기/에러 의 하나에 반응이 있었는지 알아 볼려면 FD_ISSET을
사용하여 해당 파일기술자가 반응이 잇엇는지 체크하면 된다. 반응이 있었다면
FD_ISSET은 1을 반환하고 반응이 없었다면 0을 반환한다.

profile
아크마 2007.11.22 14:27
FD, 파일 디스크립터를 이용해서 작성하시는군요..

기본기부터 착실히 배우시네요..

종종 보면 MFC에서 사용하는 CSOCKET CASYNCSOCKET부터 시작해서 하시는분들 있는데

이럴대는 소켓에 대해서 이해가 부족하게 되는거 같습니다.

또 유닉스나 리눅스에서는 사용을 못하고요..ㅋㅋ

역시 기초가 튼튼한게 중요한가봐요~~~


최근에 SUN 11과 윈도우와 통신하는걸 만들었는데 그때 참 여러가지 고민을 했는데 말이지요~

동기로 할건지 비동기로할건지부터 블럭킹해결방안, 트래픽 처리, LSB와 MSB간의 호환등등;;

지나고 나니 추억이네요 이것도.ㅋ
profile
니네임 2010.05.08 22:13
글로도 올려주셔서 감사 합니다^^
profile
컴쟁이 2012.12.27 00:05
잘보고 갑니다
profile
시나브로69 2017.06.24 16:00
좋은 자료 감사합니다.
search
List of Articles
번호 분류 제목 평점 포인트 판매자 등록일 구매수 조회 수
공지 공공의 목적으로 공유하고자 하는 소프트웨어는 '소프트웨어 자료실'에 업로드를 요청드립니다.
공지 구매후 평점 댓글을 남겨주시면 구매포인트의 20%를 돌려드립니다.
33 Software & IDEs fortran에서 수치해석 라이브러리 IMSL사용하기 [3] 무료 도시인 2014-03-04 0 215
32 Software & IDEs C# - GPS 예제 [4] 무료 달리는거북이 2010-12-03 0 3645
31 Software & IDEs 저는 학원에서 패스했습니다 ㅋ 무료 뒤집기달인y 2010-10-22 0 1993
30 Software & IDEs VS6 MFC기반에서 Rchedit 컨트롤 추가시 에러 무료 아크마 2010-10-04 0 2101
29 Software & IDEs MFC 테트리스프로그램 입니다^^ [8] 무료 초짜초짜초짜 2010-09-27 0 3104
28 Software & IDEs [Win32api/게임 ] 갤러그 [4] 무료 밍구리 2010-07-02 0 3576
27 Software & IDEs VB 에서 VC++ 처럼 메시지 이벤트 사용 [2] 무료 전자과조교 2010-05-04 0 1893
26 Software & IDEs Serial로 데이터 받아 처리하는 신체검사프로그램 [7] 무료 맑은소리 2010-04-26 0 1852
25 Software & IDEs 그리기 예제입니다 ^^ [5] 무료 전설의사나이 2010-04-10 0 1855
24 Software & IDEs MFC를 이용한 타자게임 입니다 ^^ [4] 무료 전설의사나이 2010-04-10 0 3197
23 Software & IDEs Winsock API 한글 도움말 입니다 . [6] 무료 쑤잉아 2010-04-08 0 2032
22 Software & IDEs unix network 프로그래밍 관련 자료 입니다. [2] 무료 블루미르7 2010-01-05 0 1782
21 Software & IDEs 강아지 키트를 이용하여 만들었습니다~~~ [17] 무료 kimd 2009-11-20 0 2118
20 Software & IDEs [MFC] 날짜 계산기입니다 [8] 무료 shindy 2009-10-28 0 3538
19 Software & IDEs 제어용DSP 추천합니다 [1] 무료 날아가는잡쉐 2008-09-25 0 1282
18 Software & IDEs API 시리얼통신 함수 사용방법 입니다. 참고하세요 [10] 무료 뺘쑝 2008-04-30 0 3911
17 Software & IDEs [MFC] 윈도우 크기 고정하기 [6] 무료 아크마 2008-04-28 0 3956
16 Software & IDEs 섭씨 화씨 변환 프로그램 [8] 무료 아크마 2008-04-23 0 2536
15 Software & IDEs 저.. 지금 딱 두번 글을 올려 봤는데.. 움.. 먼가 좀 바꿔야 될듯 해서..;; ㅋㅋ [1] 무료 행복하면 2007-12-03 0 1313
14 Software & IDEs c언어와 c++ 할 줄은 아는데.. 개념이 조금 부족하신분.. [14] 무료 행복하면 2007-11-29 0 1966
  • 사람이란 자기가 생각하는 만큼 결코 행복하지도 불행하지도 않다.
    - 라 로시코프
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.