12
31

   i. TCP UDP 장단점

 

네트워크 프로그램을 만들 때는 먼저 사용할 소켓 타입을 결정해야한다. 소켓에는 두가지 정보를 입력해야 하는데, 주소 체계와 소켓의 타입이다. 주소 체계에는 다음과 같은 종류가 있다.

 

Name(이름) Address Family(주소체계)
AF_INET IPv4 인터넷 주소 체계
AF_INET6 IPv6 인터넷 주소 체계
AF_LOCAL 로컬 통신 UNIX 주소 체계

 

소켓 타입에는 TCPUDP로 나뉘게 된다. TCPTransmission Control Protocol의 약자이고, UDPUser Datagram Protocol의 약자이자, 두 프로토콜 모두 전송계층에 속한다.

전송 계층이란, IP에 의해 전달되는 패킷의 오류를 검사하고 재전송 요구 등의 제어를 담당한다. 하지만 서로 다른 특징을 가지고 있다.

 

구분 TCP UDP
신뢰성 신뢰성을 위해 ACK, Checksum 등 사용 신뢰성이 없음
연결성 연결 지향성
Connection 을 맺고 통신
비 연결성
재전송 재전송 요청함
(오류 및 패킷 손실 검출시)
재 전송 없음
특징 Flow Control을 위해 Windowing 사용
속도는 다소 느려도 신뢰성을 제공
신뢰성은 보장 하지 않지만 고속 데이터 전송
실시간 전송에 적합
용도 신뢰성이 필요한 통신 총 패킷수가 적은 통신
동영상 및 음성 등 멀티미디어 통신

 

TCP는 연결 지향성이어서 Connection을 맺고 통신을 한다. 연결이 되어 있어서 전송이 되었는지 확인이 가능하다. , 신뢰성이 보장된다. UDP는 일방적으로 한 쪽에서 보내기만 한다.

그런 특성으로 UDP10byte 데이터를 보내고 싶으면 한 번에 10byte를 모두 전송되거나 10byte 전부 실패한다. 반면에 TCP 10 byte가 도착될 수도 5byte 2번 도착할 수도 1byte 10번 도착될 수도 있다.

TCP는 신뢰성이 있는 전송이 중요할 때에 사용하는 프로토콜이며, 전송 순서와 신뢰성 있는 데이터를 전송하는 장점이 있지만, UDP보다 비교적 느리다 라는 단점이 있다. UDPTCP보다 속도가 빠르고 네트워크 부하가 적다는 장점이 있지만, 신뢰성 있는 데이터 전송을 보장하지 않는다는 단점이 있다.

, 신뢰성이 요구되는 프로그램에서는 TCP를 사용하고 간단한 데이터를 고속으로 전송하고자 하면 UDP를 사용한다.

프로그래밍적으로 접근하자면 UDP는 연결이 안되어 있기 때문에, 프로그램적으로 신뢰성을 보장해줘야 한다. 또한 한 번에 받기 때문에, 나중에 받은 것이 먼저 보냈던 걸 수도 있다. 어떤 게 먼저 보낸 건지 시간 설정을 고려해야 할 것이다.

TCP는 패킷이 쪼개져서 연속적으로 들어오기 때문에 10Byte를 보냈으면 10Byte가 다 전송이 되었다는 걸 인지하고 포장해서 데이터로 써야한다. 패킷 상단에 몇 바이트를 보내는 패킷인지 명시하는 것을 고려해야한다.


Socket

소켓은 1982년 BSD Unix 4.1에서 처음 소개되었다.

현재 널리 사용되는 것은 1986년 BSD Unix 4.3에서 개정된것.

 

소켓은 소프트웨어로 작성된 통신 접속점으로

응용프로그램에서 TCP/IP를 이용하는 창구 역활을 한다.

 

윈속(WinSock)

마이크로소프트 윈도즈와 소켓의 합성어 윈도우 소켓의 약자

BSD 계열 유닉스 소켓을 참고로 하여 설계하였다.

기능은 소켓과 같은데 윈도우 최적화에 개선을 한 것이다. 

 

원속 환경설정

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "Sample.h"
#include <iostream>
#include <winsock2.h> // 헤더
#pragma comment (lib, "ws2_32.lib") // 라이브러리 추가 Ws2_32.dll 로드함

 

원속 초기화

//윈속 초기화
int WSAStartup(WORD wVersionRequested, LPWSADATA LpWSAData);
//윈속 종료 함수
int WSACleanup(void)

모든 윈속 프로그램에서 소켓 API 사용전에 윈속 초기화 함수를 먼저 호출 해야함.

윈속 2.2 버젼은 0x0202 또는 MAKEWORD(2,2)를 사용하면됨

 

소켓

SOCKET socket(int af, //주소체계 지정
			int type, // 소켓타입 지정
                int protocol); // 사용할 프로토콜 지정

반환값 : SOCKET(32비트 정수)

성공하면 새로운 소켓을 하고 실패하면 INVALID_SOCKET를 리턴함

#define SOCK_STREAM     1               /* stream socket */
#define SOCK_DGRAM      2               /* datagram socket */

stream은 TCP, dgram은 UDP 소켓으로

protocol를 0으로 두면 알아서 프로토콜이 지정이 된다.

 

아래는 예시로 클라이언트 콘솔 

TCP/IP로 호스트 port에 연결하는 코드이다.

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "Sample.h"
#include <iostream>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")

//클라이언트 
int main()
{
	WSADATA wsa;
	if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
	{
		return 0;
	}
	//소캣
	SOCKET sock = socket(AF_INET,SOCK_STREAM,0);//IP, STREAM - TCP // DGRAM- UDP, 프로토콜 안넣어도 됨
	
	//sockaddr addr;
	//addr.sa_family = AF_INET; //IP 프로토콜 쓴다.
	//addr.sa_data[14]; // ip. port
	SOCKADDR_IN sa; //공용체써서 편한 대문자 버젼
	ZeroMemory(&sa, sizeof(sa));
	sa.sin_family= AF_INET;
	sa.sin_port=htons(10000);
	sa.sin_addr.s_addr= inet_addr("192.118.0.0");
	int iRet = connect(sock,(sockaddr*)&sa,sizeof(sa)); //연결


	char szBuffer[256] = "Hello World";
	char szRecvBuffer[256] = { 0, };

	int sendByte = send(sock, szBuffer, sizeof(szBuffer), 0);

	recv(sock, szRecvBuffer, 256, 0);

	std::cout << szBuffer<<"\n";

	WSACleanup();
}
COMMENT