※네트워크 프로그래밍
▶소켓통신 연결에 대해서 기본적으로 배워보도록 하자.
먼저 기본적으로 소켓에 대해서 알아보자.
애플리케이션이 데이터를 주고 받을 수 있는 하나의 추상적인 통로이다.
애플리케이션이 자유롭게 하나의 파일로부터 데이터를 읽고 쓸 수 있는데, 소켓도 이와 비슷한 개념이다.
소켓을 사용하여 네트워크에 접속하고, 같은 네트워크에 접속중인 다른 애플리케이션과 통신할 수가 있다.
한 기기의 애플리케이션에서 소켓으로 데이터를 전송하면 다른 기기의 애플리케이션에서는 이 데이터를 받아서 읽을 수 있다.
간단히 말해서 컴퓨터를 연결해주는 소프트웨어 프로그램이라고 보면 간단하다.
아래에서 간단히 알아볼 UDP와 IPX가 이와같은 소켓 통신이다.
먼저 네트워크의 기본적인 용어만 짚고 넘어가도록하자.
domain | - 소켓이 사용되는 네트워크의 영역을 정의 |
IPC | - 창안에서 이동되는 통신을 의미 |
Network | - 2개 이상의 다른 공간의 컴퓨터가 서로 연결하는 것을 의미 |
AF_UNIX 프로세스간 통신 IPC용
AF_INET 일반 TCP/IP 인터넷 통신
AF_IPX 노벨의 IPX
AF_X25 X.25 프로토콜
Type | Protocol |
|
|
SOCK_STREAM : 연결 지향형, 여러 번 write를 호출했더라도 수신 버퍼가 충분하면 한 번의 read로 수신 가능(no boundary).
SOCK_DGRAM : 비연결 지향형, write를 여러 번 호출했으면 수신 측에서도 반드시 여러 번의 read를 통해서 모든 데이터를 수신할 수 있다(boundary).
[출처] SOCK_STREAM, SOCK_DGRAM|작성자 jingene
SOCK_STREAM : IPPROTO_TCP
SOCK_DGRAM : IPPROTO_UDP
SOCK_RAW : 소켓을 생성하는데 안에 채워넣지 않음을 의미하는 것이다.
SOCK_STREAM & IPPROTO_TCP : TCP 기반의 통신에 사용
우리는 TCP방식에 집중한다.
SOCK_DGRAM&IPPROTO_UDP:UDP 기반의 통신에 사용
SOCK_RAW&(원하는 프로토콜): RAW Socket으로 저수준에서 프로토콜을 직접 다룰 때 사용
TCP소켓
소켓생성
socket 함수 반환값.
- 성공적으로 소켓을 만들면 0보다 큰 int 값을 반환
if(-1=iSock) = socket
(★소켓의 정확한 생성을 확인하기위해서 작성되는 소스코드는 -1로 표시하지만 실제로는 0보다 작다로도 많이 사용한다.)
- 소켓지정번호, socket descriptor(소켓의 서술자 즉 소켓에 대한 정보를 가지고있는 메모리 공간을 의미한다.)라고 부른다.
말그대로 소켓기술자, 서술자 등으로 불리며 소켓에 대한 정보를 가지고 있기 때문에 해당 내용을 지시, 제어 한다.
- 소켓을 지시하며, 이를 이용해서 소켓을 제어한다.
grep sockaddr_in /usr/include -r
grep : 어떤 글자를 잡아내라라는 의미이다
sockaddr_in : 찾아내고자하는 문자열이다.
/usr/include : 해당 위치 디렉토리에가서 찾는 것을 의미한다.
-r : 모든 것을 찾아라는 의미이다.
connect 함수의 사용 예.
struct sockaddr_in serveraddr;
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_ADDR = INET_ADDR("218.234.19.87");
serveraddr.sin_port = htons(8080);
client_len = sizeof(serveraddr);
connect(server_sockfd,(struct sockaddr * ) & serveraddr, client_len);
- Intetnet TCP/IP 통신
- 218.234.19.87 주소로 연결요청
- 8080 포트에 연결된 프로그램을 요청
IP주소 -> 보관용 메모리라고 하면 이해할수 있다.
이러한 보관용 메모리를 구조체로 만들었으며
sockaddr_in 이라고 말그대로 소켓의 주소라고 하는 것이다.
ip Address와 Port번호를 저장하는 주소이다.
편지를 보내려면 받는 사람의 주소를 적어야한다. 위의 sockaddr_in구조체는 편지의 받는사람주소를 기입하는 공간과 같은 역할을 한다가 볼 수 있다.
일반적으로 port번호에서 80번은 웹에서 사용하는 번호이다.
8080은 포트번호이다. 이러한 포트번호의 중요성은 통신을 통해서 연결하여 접속하기 위한 PORT이다.
DOS창에서 기본적으로 telnet을 통해 구글에 접속하고자할때 telnet port인 21번 포트로는 접속하기 어렵다.
따라서 웹 port인 80 port를 타고 접속이 가능하다.
port는 기본적으로 2byte이다
따라서 구조체를 확인해보면
struct sockaddr_in{
{
sa_family_t sin_family; /* Address family
unsigned short int sin_port; /* Port Number
struct in_addr sin_addr; /* Internet address
/* Pad to size of 'struct sockaddr' . */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short sizeof(unsigned short int) - sizeof(struct
구조체는 예전부터 설계를 해두었기 때문에 특정용량이 되어야한다. 따라서 마지막 Pad에 해당하는 부분은 채워넣기위한 부분이라서 더미 즉 그다지 쓸모없는 값을 의미한다. 따라서 사용하지 않는 부분이다.
};
※ IP의 문자열을 숫자로 바꾸어주는 함수가 따라 존재한다?
네트워크에서 사용하는 타입의 반대개념이
host타입의 숫자가 있고
네트워크타입을 사용하는 숫자가 있는데
이를 서로 바꾸어주는 함수가있는데
Host에서 Network로 바꾸어주는 함수가
H TO N이라고 해서 htons이 있다
반대로는
NTOH즉 ntohs가 존재한다.
우리가 아는 ip주소는 실제로 문자열이라고 볼 수 있다.
이러한 문자를 숫자로 바꾸어주는 함수가 있는데
이것이 바로 inet_addr();함수이다.
※inet_addr()함수는??
→우리가 아는 ip주소는 "192.135.123.21"과 같이 숫자로되어있다. 하지만 실제로는 문자열에라고 볼 수 있는데
inet_addr()함수는 이러한 ip주소의 문자열을 숫자로 바꾸어주는 역할을 하는 것이다. 우리가 생성한 구조체에 컴퓨터가 인식할 수 있게 바꾼뒤에 주소를 넣어주면된다.
(man 3 inet_addr 을 통해서 리눅스에서 알아볼 수 있다.)
→inet_addr함수는 아래와 같이 사용하였다.
※connect함수를 통해서 소켓을 연결해보자.
→connect함수는 말그대로 생성된 소켓을 통해서 소켓 연결을 시작하는 함수이다.
사용방법은 아래와 같다.
→connect함수를 사용한 예이다.
28 connect(iSock,(struct sockaddr*)&staddr, sizeof(staddr));
29 if(0 > iRet) //connect() 실패하게되면 음수를 반환하게된다.
30 {
31 printf("\nConnect Fail!!\n\n");
32 close(iSock);
33 return 0;
34 }
▶일반적으로 소켓연결에 성공하면 양수의 값 1이 반환된다. 하지만 실패시 음수의값 -1이 반환되기 때문에 실패할 것을 고려해서 위와같이 소스코드를 작성해두는 것이다.
※완성된 소스코드이다.
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <sys/stat.h>
5 #include <arpa/inet.h>
6
7
8 int main(void)
9 {
10 int iSock;
11 struct sockaddr_in staddr;
12 int iRet;
13
14 // IPv4를 사용하고 TCP방식 사용하는 소켓을 생성
15 iSock = socket(AF_INET,SOCK_STREAM,0);
16
17 if(0 > iSock) // or ((-1)==iSock); 에러발생시
18 {
19 printf("\n소켓을 생성할 수 없음\n\n");
20 return 0;
21 }
22
23
24 staddr.sin_family = AF_INET;
25 staddr.sin_port =htons(4006); // '4006'번 port에 접속할 예정이다.
26 staddr.sin_addr.s_addr =inet_addr("192.168.10.250"); // 문자열(IP)를 int로 바꾸어주는 함수이다.
27
28 connect(iSock,(struct sockaddr*)&staddr, sizeof(staddr));
29 if(0 > iRet) //connect() 실패하게되면 음수를 반환하게된다.
30 {
31 printf("\nConnect Fail!!\n\n");
32 close(iSock);
33 return 0;
34 }
35
36 printf("\n소켓번호 : %d \n\n", iSock);
37 close(iSock); //소켓을 닫을 때 close를 사용
38 return 0;
39 }
늦어서 죄송합니다 ㅠㅠㅠㅠㅠㅠㅠㅠ
'코스웨어 > 14년 스마트컨트롤러' 카테고리의 다른 글
2014년 06월 18일 출석번호 9번 김해성 일일업무일지 (12) | 2014.06.18 |
---|---|
20140617 업무보고 김진철 출석번호 8번 (13) | 2014.06.18 |
20140616 업무보고 김재성 출석번호 7번 (14) | 2014.06.17 |
2014년 06월 13일 김용우- 네트워크_클라이언트 (0) | 2014.06.16 |
socket client source - 김해성 (0) | 2014.06.16 |
2014.06.13 클라이언트 소켓프로그램 -오두환 (0) | 2014.06.16 |
2014년 06월 13일 손병규- 네트워크_클라이언트 (0) | 2014.06.13 |
2014년 06월 13일 client 소켓 소스 양태영 (0) | 2014.06.13 |