노트 필기 잡동사니

- 서버는 PORT번호를 보통 고정시킨다. 일반적으로 0~1023 포트는 관리자 권한 없이 포트를 열 수 없다. 그러므로 될 수 있으면 0~1023번 포트는 사용하지 않도록 한다. 단 클라이언트의 경우 안쓰는 포트 중 하나를 랜덤으로 사용한다.

- 네트워크는 이기종 끼리도 통신이 가능해야 한다.

- 포트가 끊기는 데에는 어느 정도 시간이 필요하다.

- TCP/IP의 표준 데이터 저장 방식은 Big-Endian이다.(함수들도 해당) 인텔의 대부분 컴퓨터는 Little-Endian 구조이므로 데이터를 처리할 때 뒤집어 주어야 하고, 통신해 받은 데이터도 뒤집어 주어야 한다. 이들은 함수로 제공되어 있다.

- htonl : Host to Network Long, Long은 데이터 타입을 말하며, ip 주소를 처리해 줄 때 사용한다. Little -> Big

-> INADDR_ANY는 0의 값을 갖고 있다. htonl에 0의 값(혹은 INADDR_ANY)을 적으면 자동으로 유저의 ip가 들어간다.

서버는 IP가 고정되어 있어야 하므로 해당 함수를 이용함에 주의해야 하지만, 클라이언트는 유저마다 ip가 다르므로 클라이언트의 주소를 처리할 때 쓸 수 있다.

- htonsHost to Network Short, Short는 데이터 타입을 말하며, 포트 번호를 처리할 때 사용한다. Little -> Big

- ntoa : Network to ASCII, Big-Endian으로 저장된 ip주소를 문자열로 읽기 좋게 해준다.

-> C0 0A A8 63 -> 192.10.168.99

- ntohl : htonl의 반대 개념이다. Big -> Little

- ntohs : htons의 반대 개념이다. Little -> Big


Dos : Denial of Service Attack( 서비스 거부 공격 )

DDoS : Distributed Dos( 분산 서비스 거부 공격 )

근데 일반적으로 최근 컴퓨터의 성능이 매우 향상되어 DDoS공격은 잘 먹히지 않는다


Protocol Family : 프로토콜 계열, 통신 규약( TCP, UDP, 등 여러 프로토콜이 존재한다. )

Address Family : 주소 계열( IP )

INET : Inter Network(인터넷)의 약자.


grep : Linux 명령어. 파일이나 폴더에서 해당 문자열을 검색한다.

/ : vi에서 문자열을 검색.


wine : 윈도우 프로그램을 리눅스에서 구동되게 하는 유틸리티.


신뢰성 : 파일의 100% 전송을 확신하는 것. Stream을 이용한다.

-> 받았는지 확인하여 안받았으면 다시 보내고, 받았으면 다음을 보낸다. TCP는 신뢰성 통신이다. IP는 TCP에 밀접되어 있어 보통 TCP는 IP와 붙여 TCP/IP라고 한다.

비신뢰성 : 파일이 100%전송되는 것을 보장하지 못한다. Data Gram을 이용한다.

-> 받건 안받건 다음 내용을 보낸다. UDP는 비신뢰성 통신이라고 한다.


랑데부 소켓 : 외부에서 클라이언트를 받아오는 소켓(주쌤 표현으로는 얼굴마담...)

커뮤니케이션 소켓 : 내부에서 클라이언트의 데이터를 처리하는 소켓


서버의 동작 과정

 번호

이름

설명 

소켓 생성

socket 함수를 이용해 server socket을 생성하고 연다.

2

구조체 설정

소켓에 대한 정보들을 입력한다.

3

바인딩

구조체를 소켓에 적용시킨다.

4

Listen 

접속 전에 대기, 2번째 인자는 대기 최대 인원이다.(매우 빠르므로 거의 의미가 없음) 

//함수 원형 설명 추가하기

5

Accept 

접속을 수락한다 


TCP는 3 Handshake 방식으로 접속한다. 단 이 방법은 도중에 무언가 사라지면 작업에 장애를 초래할 수 있다. 이 허점을 파고들어 공격하는 것이 DDoS이다.


접속하는 방법 : VMware에서 서버를 가동한 상태에서 윈도우의 명령프롬프트를 열고 텔넷으로 리눅스에서 설정한 ip와 소스에서 설정한 포트를 입력하여(telnet xxx.xxx.xxx.xxx 9999) 접속한다.


서버 소스(server.c)

#include <stdio.h>
#include <sys/socket.h>  // 소켓 함수용 라이브러리.
#include <arpa/inet.h>
#include <stdlib.h>  // C 표준 라이브러리.
#include <string.h>
#include <unistd.h>

#define  MAXPENDING  5  // 최대 허용 대기 가능 인원

int main()
{
  int servSock;  // 서버 소켓번호는 정수형으로 이루어져 있다.
  int clntSock;  // 클라이언트 소켓.
  struct sockaddr_in echoServAddr;  //  서버 소켓 구조체(신버전)
  struct sockaddr_in echoClntAddr;  //  클라이언트 주소...
  unsigned short echoServPort;  // 서버 포트.... 9999...
  unsigned int clntLen;  // 

  int iRet;  // 잡동사니를 넣어두는 변수.

  unsigned char ucBuffer[500];  // 클라이이언트로부터 메시지를 저장하는 버퍼.
  

  echoServPort = 9999;  // 사용할 포트 번호.

  servSock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );  // Socket을 생성한다.
  // Protocol Family

  if( servSock < 0 )  // 위의 구문에서 에러가 발생했다면
  {
    printf( "Socket Function Error!\n" );
    return0 );
  }

  memset( &echoServAddr, 0sizeof( echoServAddr ) );  //해당 메모리를 전부 0으로 초기화.
  echoServAddr.sin_family = PF_INET;  // Internet Address Family
  echoServAddr.sin_addr.s_addr = htonl( INADDR_ANY );  // INADDR_ANY는 자동으로 주소를 입력시켜 준다. 직접 입력해도 되나, 메모리에 저장되는 방식에 유의해야 한다.(Little->Big(표준))
  // 서버 주소는 반드시 고정되어야 하지만 클라이언트에서는 클라이언트의 주소를 자동할당하는 것이 좋다. 컴퓨터가 바뀌어도 자동 할당됨.
  echoServAddr.sin_port = htons( echoServPort );  // 포트 번호도 Big-Endian으로 바꿔주어야 한다. short형이므로 htons
  
  iRet = bind( servSock, ( struct sockaddr * )&echoServAddr, sizeof( echoServAddr ) );
  // 열려 있는 소켓에 포트 번호, IP등을 부여한다. 바인딩
  // bind함수에 쓰이는 인자는 구형 구조체이므로 캐스팅한다.
  // 블로킹 함수가 아니다.
  
  if( iRet < 0 )  // 위의 구문에서 에러가 발생했다면
  {
    close( servSock );  // 소켓을 연 이후 에러가 났으므로 닫아주도록 한다.
    printf( "Bind Failed Error!\n" );
    return0 );
  }

  iRet = listen( servSock, MAXPENDING ); // MAX PENDING : 5

  if( iRet < 0 )  // 위의 구문에서 에러가 발생했다면...
  {  
    close( servSock );  // 소켓을 연 이후 에러가 났으므로 닫아주도록 한다.
    printf( "Listen  Failed Error!\n" );
    return0 );
  }


  clntLen = sizeof( echoClntAddr );
  clntSock = accept( servSock, ( struct sockaddr * )&echoClntAddr, &clntLen );
  // 들어오는 사람의 IP 및 정보가 요구되므로 2번째 인자가 클라이언트 정보.
  // accept는 구 자료형 형식의 함수이기 때문에 강제 캐스팅
  // clntLen : 크기.
  // accept에서는 접속이 될 때 까지 그대로 대기상태가 된다. 블로킹 함수.
  // servSock : 랑데부 소켓(외부에서 받아들이기만 한다)
  // clntSock : 커뮤니케이션 소켓. 내용을 처리할 때 쓰인다.
  
  if( clntSock < 0 )
  {
    close( servSock );  // 서버 소켓은 열려 있으므로 닫아준다.
    printf( "Accept Function Error!\n" );
    return0 );
  }
    
  printf( "Handling client IP : %s\n", inet_ntoa( echoClntAddr.sin_addr ) );
  // Network to ASCII Code(수치로만 되어있는 IP주소를 사용자가 알아볼 수 있게 문자열로 바꾸어준다.)
  
  printf( "Handling client PORT : %d\n", ntohs( echoClntAddr.sin_port ) );
  // Big-Endian으로 저장된 클라이언트의 포트 정보를 서버에 맞게 Little-Endian으로 변환하여 출력한다.
  
  while1 )
  {
    iRet = read( clntSock, ucBuffer, sizeof( clntSock ) );
    // 커뮤니케이션 소켓으로부터 값을 읽어온다.
    // read함수는 글자 수를 반환하므로 iRet에 글자수를 임시로 저장한다.
    ucBuffer[ iRet ] = 0;  // 마지막 글자는 \n(개행문자)이므로 NULL로 처리한다.
    write( 1, ucBuffer, iRet );  // 버퍼에 있는 내용을 stdout(화면)에 출력한다.

    if'q' == ucBuffer[0] )  // 첫 글자가 'q'이면 서버 프로그램을 종료한다.
    {
      break;
    }
  }

  close( servSock );  // 서버 소켓을 종료한다.
  close( clntSock );  // 클라이언트 소켓을 종료한다.
  
  return0 );  // 빠빠이
}


'Programming > TCP IP' 카테고리의 다른 글

[TCP/IP] 130613목 - 기본 IP설정, 소켓 개념(덜씀..)  (3) 2013.06.13

TCP/IP 정보 확인하기


리눅스 : ifconfig( Interface Config의 약자)

eth0 : 요즈음에는 LAN카드가 대체로 Ethernet 표준을 따르고 있으므로 Ethernet을 나타내는 eth, 장치가 한 개만 있으므로 0이 나온다.

Loopback : 자기 자신에게 패킷 보내는 것. 만약 ifconfig를 쳤을 시 lo라는 랜카드가 존재하지 않는다면 네트워크에 문제가 있을 수 있다.


윈도우 : ipconfig


설정하기


윈도우에서 설정


리눅스에서 설정

리눅스는 설정 이후 네트워크 프로그램을 재시작 해야 한다. /etc/init.d/network restart로 재실행 해주도록 한다.


용어

게이트웨이 : 다 함께 연결된 컴퓨터들은 밖에서는 전부 동일한 주소(게이트웨이)로 보게 된다.



(내가 생각해도 잘 만든 도표인 것 같다. 역시 난 시각디자인을 전공해야 했어)


DNS : 심볼 테이블과 유사한 것으로, 서버에 이름을 가져가면 해당 주소를 반환해 준다. 사용자는 구글에 접속할 때 단순히 해당 주소(http://www.google.com)을 입력하는데, 실제로는 DNS서버에 가서 해당 문자열을 검색해 그에 맞는 ip주소로 이동시켜 주는 것.

DNS 서버 : Domain Name Service를 제공하는 서버를 의미한다.

Physical Address(MAC) : 기기 고유 번호를 의미한다. 겹칠 수 없다.


방화벽(Firewall) : 아무 포트에 패킷이 들어오지 않도록 하는 것.


TCP/IP


소켓은 말 그대로 소켓에서 따온 것. 서버는 고정되어 있고 서비스를 제공하며, 클라이언트는 서버로부터 서비스를 받기 위해 서버에 접속한다.

소켓은 주소 번호와 포트 번호로 이루어진다. 소켓의 값을 읽고 쓰고 생성하고 제거하는 일련의 과정은 저수준 입출력과 매우 유사하다.


윈도우에서는 WinSock, 리눅스에서는 Sockect API를 사용한다.


서버는 포트가 일정하나, 클라이언트에서는 안 쓰는 포트를 자동으로 잡는다.( 0 ~ 65535 )


IP가 없으면 TCP/UDP가 성립 불가능하다.


Destination : 목적지

Source : 근원지

'Programming > TCP IP' 카테고리의 다른 글

[TCP/IP] 130614금 - 설명 및 서버 기초  (0) 2013.06.14

+ Recent posts