TCP

Nagle 알고리즘은 네트워크 상에서 돌아다니는 패킷들의 오버플로우를 막기 위해 1984년 제안된 알고리즘으로, 앞서 전송한 데이터에 대한 ACK 메시지를 받아야만 다음 데이터를 전송하는 알고리즘입니다. TCP상에서 적용되는 간단한 알고리즘이고, 적용여부에 따른 데이터 송수신 방식의 차이는 다음과 같습니다. 문자열 "Nagle"을 전송할 때 알고리즘을 적용했을 때와 적용하지 않았을 때의 극단적인 상황을 보여주는 예시입니다. 왼쪽 그림에서, 데이터 'N'을 보내고, ACK가 올 때까지 출력버퍼에 a, g, l, e를 쌓다가 ACK가 도착하자 데이터 'agle'를 하나의 패킷으로 보내는 모습입니다. 1바이트의 데이터를 보내더라도 패킷의 헤더정보의 크기가 수십바이트기 때문에 위 예시에선 알고리즘을 적용했을 때..
이 소켓의 옵션을 소개하기 이전에, Time-wait 상태를 얘기하겠습니다. 우리가 서버를 키고 종료할 때 컨트롤-C 등으로 강제 종료하고 즉시 다시 키려고 시도하면 bind()함수에서 에러가 발생하는 모습을 이미 보셨을 수도 있습니다. 이 상황이 발생한 이유는 Time-wait 상태 때문인데, 데이터 송수신 중에 먼저 연결의 종료를 요청한 호스트는 Time-wait 상태를 거치게 됩니다. 만약 클라이언트와 통신 중에 위의 예시와 같이 강제종료 하는 등 서버가 먼저 종료되면, 서버가 Time-wait 상태를 거치게 되는 것입니다. 이 상태는 소켓이 소멸되지 않고 남아있게 됩니다. (TCP에서 송수신이 종료되는 과정을 모르신다면 https://pupuduck.tistory.com/35를 참고해주시기 바랍니..
소켓이 생성되면 기본적으로 입력버퍼와 출력버퍼가 생성됩니다. SO_RCVBUF는 입력버퍼의 크기와 관련된 옵션이고 SO_SNDBUF는 출력버퍼의 크기와 관련된 옵션입니다. 이 두 옵션을 이용해 입출력 버퍼의 크기를 참조할 수 있고, 변경 또한 할 수 있습니다. 다음 소스코드는 입출력버퍼의 크기를 얻는 예제입니다. #include #include #include #include void error_handling(char *message); int main(int argc, char *argv){ int sock; int snd_buf, rcv_buf, state; socklen_t len; sock=socket(PF_INET, SOCK_STREAM, 0); // 출력버퍼의 크기를 얻는다. len=size..
프로토콜 레벨 SOL_SOCKET에 있는 SO_TYPE 옵션은 소켓의 타입정보를 확인하는 옵션입니다. #include #include #include #include void error_handling(char *message); int main(int argc, char *argv){ int tcp_sock, udp_sock; int sock_type; socklen_t optlen; int state; optlen=sizeof(sock_type); // tcp/udp 소켓 생성 tcp_sock=socket(PF_INET, SOCK_STREAM, 0); udp_sock=socket(PF_INET, SOCK_DGRAM, 0); //tcp/udp 소켓 생성 시 2번째 인자로 들어간 상수 값 출력 print..
지금까지 소켓을 생성하고 따로 설정을 하는 과정 없이 바로 사용해왔습니다. 이 경우 기본적으로 설정되어 있는 소켓의 특성으로써 데이터를 송수신하게 됩니다. 그러나 이미 활성화되어 있는 PORT 번호에 할당을 하게 하는(SO_REUSEADDR) 등 소켓의 특성을 변경시켜야 하는 경우도 발생합니다. 소켓의 옵션은 많은 종류가 존재하는데, 프로토콜 레벨로 나눴을 때 SOL_SOCKET, IPPROTO_IP, IPPROTO_TCP가 존재합니다. 각 레벨에는 여러 옵션들이 있는데, 예를 들어 SOL_SOCKET 프로토콜 레벨에는 SO_TYPE 옵션이 있습니다. 먼저 옵션을 참조하고 변경하는 함수를 살펴보겠습니다. #include int getsockopt(int sock, int level, int optname..
#include struct hostent* gethostbyname(const char* hostname); // success: hostent 구조체 변수의 주소값 fail: NULL 포인터 위 함수를 이용하면 문자열 형태의 도메인 이름으로 IP 주소 정보를 얻을 수 있습니다. 위 함수의 반환 자료형인 hostent 구조체의 정의는 다음과 같습니다. struct hostent{ char * h_name char ** h_aliases; int h_addrtype; int h_length; char ** h_addr_list; } IP주소 말고도 여러 정보들을 반환해주는 것을 볼 수 있습니다. h_name은 공식 도메인 이름이 문자열로 저장됩니다. 해당 홈페이지를 대표하는 도메인 이름이라는 의미지만 우..
Domain Name System, DNS란 IP주소와 도메인 이름 사이에서의 변환을 수행하는 시스템입니다. DNS의 중심에는 DNS 서버가 존재합니다. 티스토리의 IP주소인 121.53.105.234를 직접 입력하면 티스토리의 페이지를 볼 수 있습니다. 그러나 일반적으로는 티스토리의 도메인 이름인 www.tistory.com을 입력해서 티스토리에 접속하게 됩니다. 둘 모두 똑같이 티스토리에 접속할 수 있습니다. 다만 접속 과정에서는 차이가 있습니다. 도메인 이름은 서버에 부여된 가상의 주소입니다. 만약 도메인 이름으로 접속하게 되면 컴퓨터에 저장되어있는 디폴트 DNS 서버의 주소로 변환을 요청하고 해당 도메인 이름의 IP 주소를 얻어서 서버로 접속하게 됩니다. 일반적으로 IP주소를 외우는 것보다 도메인..
TCP에서는 연결과정보다 중요한 것이 종료과정인데, 종료과정에서는 예상치 못한 일이 발생할 수 있기 때문입니다. close 함수 호출은 송수신을 바로 불가능하게 만드는 완전종료를 의미합니다. 만약 호스트 B가 전송한 데이터가 호스트 A가 꼭 전송받아야 하는데 A가 close를 호출해버리면 호스트 B가 전송한 데이터는 소멸됩니다. 따라서 송신은 가능하지만 발신은 종료하거나 또는 그 반대를 하게 해주는, 데이터의 송수신에 사용되는 스트림의 일부만 종료(half-close)하는 방법이 제공됩니다. 여기서 스트림이란 말이 사용됐는데, 소켓을 통해 두 호스트가 연결되고 데이터의 송수신이 가능한 상태를 스트림이 형성된 상태라고 합니다. 스트림은 단방향성을 가지고 있어, 서로 송수신을 주고받으려면 (양방향 통신을 하..
푸더기
'TCP' 태그의 글 목록 (3 Page)