2015년 5월 18일 월요일

네트워크 (2)

소켓의 생성방법을 이해해보자!

프로토콜: "컴퓨터 상호간의 대화에 필요한 통신 규약"

소켓의 생성: 호스트가 통신을 하기 위해 필요한 리소스를 할당하는 것

필요한 인자
1) domain : 프로토콜 체계
   ex) PF_INET, PF_INET6, PF_LOCAL, PF_PACKET, PF_IPX
2) type : 전송 타입 설정
   // 하나의 프로토콜 체계 안에서도 데이터 전송 방법이 여러 가지 있을 수 있다.
  1. SOCK_STREAM(연결 지향형)
     에러나 데이터의 손실 없이 무사히 전달
     전송하는 순서대로 데이터가 전달
     전송되는 데이터의 경계가 존재하지 않는다.
   2. SOCK_DGRAM(비연결 지향형)
      전송되는 순서에 상관없이 가장 빠른 전송을 지향한다.
      전송되는 데이터는 손실될 수도 있고 에러가 발생할 수도 있다.
      전송되는 데이터의 경계가 존재
      한번에 전송되는 데이터의 크기는 제한된다.
3) protocol : 특정 프로토콜 지정

주소 체계와 데이터 결정(주소 할당하는 방법)

IP 주소: 인터넷상에 존재하는 호스트들을 구분하기 위한 32비트 주소 체계

네트워크 주소: 네트워크를 구분해 주는 ID
ex)
                                    특정 호스트를 찾아가는 순서
      1) 4바이트 IP주소 중에서 네트워크 주소만을 참조해서 찾아간다.(203.211.217)
      2) 호스트 주소를 참조한다.

Port란??
*IP주소로는 인터넷에 연결되어 있는 컴퓨터들을 구분하여 줄 수는 있어도 컴퓨터 안에서 실행되고 있는 프로그램까지 구분하지는 못한다.
Port는 실행되는 프로그램을 구분해줌
범위는 0에서 65525(2바이트) <= 0부터 1023은 예약되어 있는 Port이므로 사용이 제한됨

주소 정보의 표현(IP 주소, Port)
1) 1Pv4의 주소 체계를 나타내는 구조체
struct sockaddr_in{
sa_family_t               sin_family       // 주소 체계
uint16_t                  sin_port         // 16비트 TCP/UDP Port
struct in_addr           sin_addr;       // 32비트 IPv4 주소
char                       sin_zero[8];    // 사용되지 않음
};
struct in_addr {
        sint32_t                   s_addr;        // 32비트 IPv4 인터넷 주소
};
2) sockaddr_in 구조체 정보
- sin_family : 프로토콜 체계마다 주소체계가 다르다.
     ex) AF_INET, AF_INET6, AF_LOCAL
- sin_port : 16 port 정보를 대입해준다.(네트워크 바이트 순서)
- sin_addr: 32비트 IP 주소 정보를 대입해준다.(네트워크 바이트 순서)

네트워크 바이트 순서
1) Big-Endian 표현 방식 => 네트워크 바이트 순서
    0x12 0x34 0x56 0x78
2) Little-Endian 표현 방식
    0x78 0x56 0x34 0x12

* 시스템이 Little-Endian 방식을 사용할 경우, 네트워크를 통해 데이터를 전송하기 전에  Big-Endian 방식으로 데이터를 변경해서 보내야 하고, 받을 때도 전송되어 오는 데이터를 역순으로 조합해야 한다.


바이트 순서 변환

' h ' : host byte order                        ' n ' : network byte order
' s ' : short( 16bit )  => port 정보         ' l ' :  long( 32bit ) => IP 주소

ex)
- unsigned short htons(unsigned short)
  16 비트 데이터를 Host Byte 순서에서 Network Byte 순서로 바꾸어 준다는 의미이다.

인터넷 주소 변환
ex) 203.212.114.26 을 unsigned long 값으로 변환해야 한다.

1) inet_addr(const chat *string)
  인자값으로 Dotted-Decimal Notation( ex) 203.212.114.26 ) 문자열의 포인터를 넘겨주게 되면, 해당하는  unsigned long 타입의 데이터값을 리턴
2) inet_aton() : inet_addr 함수보다 개선된 데이터 변환 함수
 개선된 방향
만약 inet_addr 함수를 사용할 경우 변환된 데이터가 unsigned long 타입의 값으로 리턴되기 때문에, 리턴한 값을 주소 정보 구조체 sockaddr_in 안에 선언되어 있는 in_addr 구조체 안에 대입하는 과정을 거쳐야 한다. 
BUT,!!  inet_aton 함수를 사용할 경우 대입하는 과정을 따로 거치지 않아도 된다.

+3) inet_ntoa()
 네트워크 바이트 순서의 32비트 값을 Dotted-Decimal Notation으로 변환하는 함수.

인터넷 주소 초기화

struct sockaddr_in addr;
// 인터넷 주소 정보를 나타내는 구조게 변수 생성
char *serv_port = " 9190 ";
memset(&addr, 0, sizeof(addr_len));
// 인자로 전달된 구조체 변수를 0으로 초기화해줌
addr.sin_family = AF_INET;
// ' 프로토콜 체계 ' 설정
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(atoi(serv_port));

주소 정보 할당하기(소켓에 주소를 할당)

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);
인자
- sockfd: 주소를 할당하고자 하는 소켓의 파일 디스크립터
- myaddr: 할당하고자 하는 주소 정보를 지니고 있는 sockaddr_in 구조체 변수의 포인터
- addrlen : 인자로 전달된 주소 정보 구조체의 길이



2015년 5월 9일 토요일

소스 분석

까먹어서 내가 친 소스를 내가 분석하다니... 노답
-서버
ChatServer 클래스
생성자: Vector(5,5)
giveAndTake 메소드 //서버를 실행시키는 메소드
서버 소켓 요청을 받아들이고 ServerSocketThread를 돌림
addClient 메소드
벡터에 클라이언트 추가
removeClient 메소드
벡터에서 클라이언트 제거
broadCasting 메소드
ServerSocketThread을 클라이언트에 캐스팅하고 Thread를 통해 메시지를 보낸다.

ServerSocketThread 클래스
생성자: (ChatServer, Socket)
sendMessage 메소드
문자열을 받아 출력
run
BufferedReader, PrintWriter를 만들어서 첫번째는 닉네임 두번째부터는 메시지를 주고 받을 수 있게 ChatServer의 broadCasting 메소드를 받아온다.

-클라이언트
StartingJFrame 클래스 // 클라이언트를 만들때 import하는 클래스
                             // JFrame를 상속 , GUI 메인 클래스에서 상속해감
intFrame 메소드
너비와 높이가 모니터보다 크면 최대화, 초기 위치 설정
processWindow 메소드
창 닫을 때의 이벤트 설정
setMainJPanel 메소드
Component를 추가

ClientGui 클래스 // JPanel을 상속받음
생성자:(JFrame, String ip, int port)
         ip 와 port 를 받아 Socket 객체를 새로 만든다.
actionPerformed 메소드
// requestFocus: 입력을 받게 되면 맨 앞의 창으로 띄어지게 된다.
giveAndTake 메소드
PrintWriter, BufferedReader 객체 생성 -> Thread 생성 -> 시작
run
textArea에 친 문자열을 받아들인다.


2015년 5월 6일 수요일

네트워크 (1)

$$ C언어를 기반으로 씀

네트워크 프로그래밍: 호스트들이 데이터를 주고 받을 수 있도록 프로그램을 구현하는 것

소켓의 이해
1) 전화기를 산다. == 소켓을 생성(Socket 함수)
2) 전화번호를 부여받는다. ==  소켓의 IP 주소 할당(Bind 함수)
3) 전화기를 케이블에 연결한다. == 소켓을 연결요청이 가능한 상태로 만듬(listen 함수)
4) 전화벨이 울리면 수화기를 든다. == 연결 요청이 들어오면 요청을 수락함(accept 함수)

클라이언트 소켓의 이해
1) 전화를 건다 == 서버에게 연결을 요청함(connect 함수)
??? 클라이언트에 전화번호를 할당하는 코드가 없다 ????

파일 조작하기
1) Low-Level == "시스템이 직접 제공해 주는"
2) 파일 디스크립터
  시스템이 만들어 놓은 것을 가리키기 좋게 하기 위해 시스템이 우리들에게 건네주는 숫자
   0 = 표준 입력
   1 = 표준 출력
   2 = 표준 에러 출력
   3
   4 ... 이런 식으로 차례로 넘버링이 됨
3) File 열기(open 함수)
   (파일의 경로를 포함하는 이름, 열고자 하는 파일의 모드)
                         O_CREAT, O_TRUNC, O_APPEND, O_RDONLY, O_WRONLY, O_RDWR
4) File 닫기(close 함수)
   (파일 디스크립터)
5) 데이터 쓰기(write 함수)
   (파일 디스크립터, 전송할 데이터를 가지는 버퍼의 포인터, 전송할 데이터의 바이트 수)
6) 데이터  읽기(read 함수)
   (파일 디스크립터, 수신할 데이터를 가지는 버퍼의 포인터, 수신할 데이터의 바이트 수)

윈속 기반의 데이터 입출력 함수
데이터를 입출력할 수 있는 기본적인 함수
send 함수 == 데이터를 전달할 때  옵션을 줄 수 있는 write 함수
(데이터를 전송할 호스트에 연결된 소켓의 핸들,
 전송할 데이터를 저장하고 있는 버퍼를 가리키는 포인터,
 전송할 바이트 수,
 함수 호출 시, 여러가지 옵션)

recv 함수
(데이터를 수신할 호스트에 연결된 소켓의 핸들,
 수신할 데이터를 저장하고 있는 버퍼를 가리키는 포인터,
 수신할 바이트 수,
 함수 호출 시, 여러가지 옵션)