Step 1 - 클라이언트가 서버에게 SYN 보내기 (SYN, Seq=X): 연결 설정 단계에서 클라이언트가 서버에게 연결을 요청하는 SYN 패킷을 보냅니다. 이 패킷은 클라이언트의 초기 순서 번호(X)를 포함하고, 연결을 시작함을 나타냅니다.
Step 2 - 서버가 클라이언트에게 응답하기 (SYN, ACK, Seq=Y, Ack=X+1): 서버는 클라이언트의 요청을 받고, 클라이언트의 순서 번호를 확인한 후 자신의 순서 번호(Y)와 함께 SYN/ACK 패킷을 보냅니다. 이것은 연결 수락을 의미하며, 서버는 다음에 올 것으로 예상되는 데이터 패킷의 순서 번호(X+1)를 보냅니다.
Step 3 - 클라이언트가 서버에게 응답하기 (ACK, Seq=X+1, Ack=Y+1): 클라이언트는 서버의 응답을 받고, 서버의 순서 번호(Y)를 확인한 후 ACK 패킷을 보냅니다. 이것은 서버가 연결을 수락했음을 확인하고, 클라이언트가 서버의 예상 순서 번호(Y+1)로부터 데이터를 보낼 것임을 나타냅니다.
필요성:
3-way handshake는 양쪽 간에 상호 동의된 초기 순서 번호를 설정하고, 연결을 설정하며, 통신을 시작하는 데 필요합니다. 이 단계가 없으면 데이터 통신이 시작되지 않습니다.
TCP 4-way Handshake (연결 해제):
Step 1 - 클라이언트가 서버에게 연결 종료 요청 (FIN, Seq=X): 데이터 통신이 끝나면 클라이언트는 서버에게 연결 종료를 요청하는 FIN 패킷을 보냅니다. 이것은 클라이언트가 더 이상 데이터를 보내지 않을 것임을 나타냅니다.
Step 2 - 서버가 클라이언트에게 응답하기 (ACK, Seq=Y, Ack=X+1): 서버는 클라이언트의 FIN 요청을 받고 확인하기 위해 ACK 패킷을 보냅니다. 그러나 서버는 아직 데이터를 보내기 위해 준비 중입니다.
Step 3 - 서버가 클라이언트에게 연결 종료 요청 (FIN, Seq=Z, Ack=X+1): 서버가 데이터 전송을 마치면, 서버는 연결 종료를 요청하는 FIN 패킷을 클라이언트에게 보냅니다. 이것은 서버가 클라이언트에게 더 이상 데이터를 보내지 않을 것임을 나타냅니다.
Step 4 - 클라이언트가 서버에게 응답하기 (ACK, Seq=X+1, Ack=Z+1): 클라이언트는 서버의 FIN 요청을 받고, 클라이언트도 더 이상 데이터를 보내지 않을 것임을 나타내는 ACK 패킷을 보냅니다. 이로써 연결이 종료됩니다.
필요성:
4-way handshake는 양쪽 간의 데이터 통신이 완료되고 연결이 종료됨을 보장합니다. 이 단계가 없으면 연결이 계속 유지될 수 있으며, 다른 데이터 전송이 불가능합니다.
"SYN"은 "Synchronize"의 약자로 동기입니다.
"ACK"는 "Acknowledgment"의 약자로 승인입니다.
"FIN"은 "Finish"의 약자로 종료입니다. 그 과정을 리눅스를 통해 3way, 4way인 것이 보입니다.
중간의 P의 경우, 패킷의 약자로 데이터 패킷을 전송하는 과정입니다.
TCP와 UDP를 그림으로 표현했을때 다음과 같습니다.
TCP (Transmission Control Protocol)
연결 지향 방식, 패킷 교환방식
3way handshaking 으로 연결 4way handshaking으로 해제
흐름제어 - 송.수신측의 데이터 처리속도 차이 줄이기 위함, receiver가 현재 상태를 sender에게 피드백해 패킷 수를 조절
혼잡 제어 - 송신측의 데이터 전달과 네트워크 데이터 처리 속도 차이를 해결 하기 위함
위 두가지 기능 가능
높은 신뢰성- 낮은 성능
전이중(각각의 독립된 회선 사용), 점대점(1대1통신) 방식
각각의 패킷들은 연결되어있으며 번호가 매겨짐
신뢰성있는 전송이 필요할때 사용
가변길이 헤더
UDP (User Datagram Protocol)
비연결형 방식, 데이터그램 방식
정보를 주고받을떄 신호절차를 가지고 있지 않음
UDP헤더의 CheckSum 필드로 최소한의 오류 검출
낮은 신뢰성 -높은 성
각각의 패킷들은 독립되어있다
빠른 전송이 필요할때 사용
고정 길이 헤더
일반적으로는 저런 내용이지만 UDP는 커스터마이징이 가능하며 개발자의 역량에 따라서 UDP를 이용해
월드 와이드 웹(World Wide Web a.k.a WWW)과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식으로 자원을 정의하고 자원에 대한 주소를 지정하는 방법 전반에 대한 패턴
REST란, REpresentational State Transfer 의 약자이다. 여기에 ~ful 이라는 형용사형 어미를 붙여 ~한 API 라는 표현으로 사용된다. 즉, REST 의 기본 원칙을 성실히 지킨 서비스 디자인은 'RESTful'하다라고 표현할 수 있다.
REST가 디자인 패턴이다, 아키텍처다 많은 이야기가 존재하는데, 하나의 아키텍처로 볼 수 있다. 좀 더 정확한 표현으로 말하자면, REST 는 Resource Oriented Architecture 이다. API 설계의 중심에 자원(Resource)이 있고 HTTP Method 를 통해 자원을 처리하도록 설계하는 것이다.
RESTful 하게 API 를 디자인 한다는 것은 무엇을 의미하는가.(요약)
리소스 와 행위 를 명시적이고 직관적으로 분리한다.
리소스는 URI로 표현되는데 리소스가 가리키는 것은 명사로 표현되어야 한다.
행위는 HTTP Method로 표현하고, GET(조회), POST(생성), PUT(기존 entity 전체 수정), PATCH(기존 entity 일부 수정), DELETE(삭제)을 분명한 목적으로 사용한다.
Message 는 Header 와 Body 를 명확하게 분리해서 사용한다.
Entity 에 대한 내용은 body 에 담는다.
애플리케이션 서버가 행동할 판단의 근거가 되는 컨트롤 정보인 API 버전 정보, 응답받고자 하는 MIME 타입 등은 header 에 담는다.
header 와 body 는 http header 와 http body 로 나눌 수도 있고, http body 에 들어가는 json 구조로 분리할 수도 있다.
API 버전을 관리한다.
환경은 항상 변하기 때문에 API 의 signature 가 변경될 수도 있음에 유의하자.
특정 API 를 변경할 때는 반드시 하위호환성을 보장해야 한다.
서버와 클라이언트가 같은 방식을 사용해서 요청하도록 한다.
브라우저는 form-data 형식의 submit 으로 보내고 서버에서는 json 형태로 보내는 식의 분리보다는 json 으로 보내든, 둘 다 form-data 형식으로 보내든 하나로 통일한다.
다른 말로 표현하자면 URI 가 플랫폼 중립적이어야 한다.
어떠한 장점이 존재하는가?
Open API 를 제공하기 쉽다
멀티플랫폼 지원 및 연동이 용이하다.
원하는 타입으로 데이터를 주고 받을 수 있다.
기존 웹 인프라(HTTP)를 그대로 사용할 수 있다.
단점은 뭐가 있을까?
사용할 수 있는 메소드가 한정적이다.
분산환경에는 부적합하다.
HTTP 통신 모델에 대해서만 지원한다.
TDD
Test-Driven Development(TDD)는 매우 짧은 개발 사이클의 반복에 의존하는 소프트웨어 개발 프로세스이다. 우선 개발자는 요구되는 새로운 기능에 대한 자동화된 테스트케이스를 작성하고 해당 테스트를 통과하는 가장 간단한 코드를 작성한다. 일단 테스트 통과하는 코드를 작성하고 상황에 맞게 리팩토링하는 과정을 거치는 것이다. 말 그대로 테스트가 코드 작성을 주도하는 개발방식인 것이다.
함수형 프로그래밍
함수형 프로그래밍의 가장 큰 특징 두 가지는 immutable data와 first class citizen으로서의 function이다.
immutable vs mutable
우선 immutable과 mutable의 차이에 대해서 이해를 하고 있어야 한다. immutable이란 말 그대로 변경 불가능함을 의미한다. immutable 객체는 객체가 가지고 있는 값을 변경할 수 없는 객체를 의미하여 값이 변경될 경우, 새로운 객체를 생성하고 변경된 값을 주입하여 반환해야 한다. 이와는 달리, mutable 객체는 해당 객체의 값이 변경될 경우 값을 변경한다.
first-class citizen
함수형 프로그래밍 패러다임을 따르고 있는 언어에서의 함수(function)는 일급 객체(first class citizen)로 간주된다. 일급 객체라 함은 다음과 같다.
변수나 데이터 구조안에 함수를 담을 수 있어서 함수의 파라미터로 전달할 수 있고, 함수의 반환값으로 사용할 수 있다.
할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
함수를 리터럴로 바로 정의할 수 있다.
Reactive Programming
반응형 프로그래밍(Reactive Programming)은 선언형 프로그래밍(declarative programming)이라고도 불리며, 명령형 프로그래밍(imperative programming)의 반대말이다. 또 함수형 프로그래밍 패러다임을 활용하는 것을 말한다. 반응형 프로그래밍은 기본적으로 모든 것을 스트림(stream)으로 본다. 스트림이란 값들의 집합으로 볼 수 있으며 제공되는 함수형 메소드를 통해 데이터를 immutable 하게 관리할 수 있다.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
}
}
}
using = using은 말 그대로 '사용하다'라는 의미를 가지고 있습니다.바로 네임스페이스 System을 사용한다는 말과 같습니다. using을 이용하면, 전체 이름을 참조하지 않고 선언된 네임스페이스 내부 개체들에 접근할 수 있어 불필요한 타이핑을 막습니다.
namespace = 네임스페이스(namespace)는 관련된 구조체, 클래스, 델리게이트, 인터페이스 등을 그룹화 한것을 말합니다. 예를 들어서, System.Collections.Generic에는 제네릭 컬렉션을 정의하는 클래스와 인터페이스들이 들어있습니다. 또 System.Linq에는, LINQ를 사용하는 쿼리를 지원하는 클래스와 인터페이스들이 들어있습니다. 이처럼 네임스페이스는 사용하기 편리하게끔 성격이 비슷한 것들을 묶어놓는 것과 같습니다.
main =static void Main는 메소드(method)이며, 메인(main) 메소드는 그중에서 가장 중요한 메소드 이며, 프로그램의 최초의 진입점(Entry Point)을 나타냅니다. 모든 프로그램에는 메인 메소드가 반드시 존재해야하며, 메인 메소드가 시작되면 프로그램이 시작되며, 종료되면 프로그램도 같이 종료됩니다. 여기서 static는 한정자로 정적인 메소드를 의미하며, void는 반환 형식으로 반환 값이 없음을 의미합니다.
< 자리표시자 >
프로그램 실행 결과를 화면에 출력할 때 사용하는 출력문 등에서는 자리 표시자(틀) 개념을 이용해서 출력 서식을 지정할 수 있습니다.{n}형태로{0},{1},{2}순서대로 자리를 만들고 그다음에 있는 값을 차례로 넘겨받아 출력합니다.{0},{1}식으로 뒤에 이어 나올 값에 대한 자리 번호(인덱스)를 지정해 놓는 방법을 자리 표시자(place holder)또는 서식 지정자(format specifier)라고 합니다. 번호 인덱스는 0부터 시작합니다. 다음 코드를 살펴보세요.
Console.WriteLine("{0}", "Hello, C#");
WriteLine()에{0}형태로 0번째 자리를 만들어 놓으면 콤마 뒤에 있는"Hello, C#"문자열이{0}자리에서 실행됩니다.
오버로딩 (Overloading)과 오버라이딩 (Overriding)은 객체 지향 프로그래밍에서 메소드를 다룰 때 사용되는 개념입니다.
1.오버로딩 (Overloading): 메소드 오버로딩은 한 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것입니다. 이 메소드들은 매개변수의 수, 타입 또는 순서가 다르기 때문에 서로 다른 기능을 수행할 수 있습니다. 또한 컴파일러가 호출되는 매개변수를 기준으로 적절한 메소드를 선택합니다. 메소드 오버로딩을 사용하면 코드를 간결하게 유지하면서 동일한 기능을 하는 메소드들을 하나의 이름으로 그룹화할 수 있습니다.
public class Calculation
{
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
}
2. 오버라이딩 (Overriding): 메소드 오버라이딩은 기반 클래스(base class)에 있는 메소드를 파생 클래스(derived class)에서 재정의하여 사용하는 것입니다. 이를 통해 파생 클래스는 부모 클래스의 메소드를 같은 이름과 시그니처로 사용할 수 있지만, 다른 동작을 수행하도록 구현할 수 있습니다. 오버라이딩을 사용하면 기반 클래스의 기본 기능을 변경하거나 확장해서, 더 구체적이고 맞춤화된 동작을 제공할 수 있습니다.
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("알 수 없음");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("멍멍");
}
}
• 리액트를 사용하는 이유: 최소 단위의 렌더링을 위해 • useState(): 변수, 변수를 제어하는 함수로 구성되며 변하는 값을 제어, 해당 부분의 리렌더링을 위함 • props: 태그의 속성 값을 함수의 아규먼트 처럼 컴포넌트에 값을 전달해준다. • useEffect(): 코드의 실행 시점을 관리할 수 있는 선택권을 얻는 방어막 같은 존재, 디펜던시가 없을 경우 최초 1회 실행, 있을 경우 해당 값이 변할 경우 실행한다. 이 때 디펜던시는 여러개 입력이 가능하다.
🏴 부모 컴포넌트에서 리렌더링이 일어날 경우 모든 자식들이 리렌더링이 된다.(wa can use memo) 🏴 propType을 설치하고 props의 타입을 지정해 줄 수 있다. 이 때 isRequired로 필수값을 지정 가능
useEffect는 state의 상태를 감지 변경이 있을 때란 해당 컴포넌트를 랜더링한다. useState(function(), []) [] 로 3가지 경우의 수 존재 ex) a, b 스테이트 1. 빈 배열을 넣는 경우, 최초 1회 랜더링 될 때만 실행한다. 2. [a] 하나의 state만 넣는 경우 a가 변경될 경우만 랜더링한다. 3. [a, b] a나 b중 하나가 값이 변경 될 때 랜더링한다.
useEffect 왜 써? 렌더링이 계속 된다면, 특히 특정 api를 불러오게 되는 경우 계속해서 불러오는 문제가 생길 수 있다. state를 변경할 때, 계속해서 렌더링 되는 문제점이 존재한다. 많은 state가 존재한다면 성능 저하 문제가 발생할 수 있다. 이런 문제를 해결하기 위해 사용한다.
(node:17836) [DEP0123] DeprecationWarning: Setting the TLS ServerName to an IP address is not permitted by RFC 6066. This will be ignored in a future version. (Use `node --trace-deprecation ...` to show where the warning was created) 데이터베이스 연결에 실패했습니다.
originalError: ConnectionError: Failed to connect to 110.10.130.21:1433 - C84E0000:error:0A0000BF:SSL routines:tls_setup_handshake:no protocols available:c:\ws\deps\openssl\openssl\ssl\statem\statem_lib.c:124:
encrypt: false로 변경함으로써 SSL/TLS 암호화를 사용하지 않게 되어 영향을 미칠 수 있습니다. 이것은 서버가 SSL/TLS 암호화를 지원하지 않을 때 문제를 해결할 수 있습니다. 하지만 보안상의 문제로 데이터 전송이 암호화되지 않게 됩니다. trustServerCertificate: true 옵션을 추가하여 서버의 인증서를 무조건 신뢰하도록 설정했습니다. 이 변경 사항으로 인해 클라이언트가 서버의 인증서를 확인하지 않고 연결을 수락하게 됩니다. 인증서가 올바르지 않거나, 자가 서명된 인증서를 사용하는 경우에도 연결에 성공할 수 있습니다. 그럼에도 불구하고 이 설정은 보안상 좋지 않은 선택이며 데이터 공격에 취약해질 수 있습니다. cryptoCredentialsDetails옵션을 수정하여 최소 TLS 버전을 'TLSv1'로 변경했습니다. 이것은 이전에 발생한 TLS 버전 불일치 문제를 해결하는 데 도움이 되었을 수 있습니다. 변경된 코드는 연결 문제를 일시적으로 해결했지만, 중요한 것은 데이터베이스와 클라이언트 사이의 전송에 암호화된 연결을 사용하도록 설정하는 것입니다. SSL/TLS를 사용하여 데이터를 암호화하고, 유효한 서버 인증서를 사용하여 서버에 대한 신뢰를 높이는 것이 좋습니다. 이러한 설정을 적용하기 위해 데이터베이스 서버 관리자와 협력하는 것이 필요할 수 있습니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
// GET: Home
public string Index()
{
return "My first Application!";
}
}
}
위 코드는 Home 컨트롤러에서 Index로 접속가능하게 해준다.
다음과 같은 url로 접속 가능한 이유는 App_start 폴더에 있는 Config에서 설정이 자동으로 되어 있기 때문이다.
< 컨트롤러 >
컨트롤러는 클래스,
액션은 메서드,
아이디는 매개변수라고 생각하면 된다.
새로운 컨트롤러 Board를 만들어보자.
컨트롤러 폴더에서 우클릭 + 추가를 통해 새로운 컨트롤러 생성.
namespace WebApplication1.Controllers
{
public class BoardController : Controller
{
// GET: Board
public string List(int? Id)
{
if (Id == null)
return "Error Message #1";
return "보드 리스트: " + Id.Value;
}
}
}
namespace WebApplication1.Models
{
public class Document
{
// prop 쓰고 tab을 누르면 빠르게 작성가능
public int Document_Number { get; set; }
public string Title { get; set; }
public string Writer { get; set; }
}
}
데이터의 처리를 위해 새폴더를 만들고 새로운 클래스 파일을 만들어줍니다.
namespace WebApplication1.Data
{
public class DocumentData
{
public List<Document> Documents
{
get
{
return new List<Document>
{
new Document{ Document_Number = 1, Title="공지1", Writer="홍길동"},
new Document{ Document_Number = 2, Title="공지2", Writer="임꺽정"},
new Document{ Document_Number = 3, Title="공지3", Writer="변사또"},
};
}
}
}
}
모델폴더에 데이터 처리를 위한 클래스를 새로 만들어준다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication1.Data;
namespace WebApplication1.Models
{
public class DocumentActs
{
public List<Document> GetDocuments()
{
DocumentData documentData = new DocumentData();
var documents = documentData.Documents;
return documents;
}
}
}
그리고 보드컨트롤러로 가서 요청을 한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models; //추가
namespace WebApplication1.Controllers
{
public class BoardController : Controller
{
// GET: Board
public ActionResult List(int? Id)
{
if (Id == null)
return Content("Error Message #1");
DocumentActs documentActs = new DocumentActs();
var documents = documentActs.GetDocuments();
return View(documents);
}
}
}
DocumentActs documentActs = new DocumentActs();
var documents = documentActs.GetDocuments();
return View(documents);
< ViewBag & ViewData >
데이터를 전달하는 방법은 다음과 같습니다.
View(object model)
public ActionResult List()
{
DocumentActs documentActs = new DocumentActs();
var documents = documentActs.GetDocuments();
return View(documents);
}
이 경우 하나의 모델데이터만 전달할 수 있기 때문에 여러 데이터를 전달하려 한다면 한계가 있습니다.
그래서 ViewBag&ViewData가 필요합니다.
public ActionResult List()
{
DocumentActs documentActs = new DocumentActs();
MemberActs memberActs = new MemberActs();
var documents = documentActs.GetDocuments();
var member = memberActs.GetMember(1);
ViewBag.Member = member;
return View(documents);
}
View()는 한개의 매개변수만 담을 수 있으니,
ViewBag을 통해 다른 매개변수를 저장하고 사용합니다.
<p>
@ViewBag.Member.Name 님 환영합니다.
</p>
ViewData는 다음과 같이 사용할 수 있습니다.
ViewData["Members"] = member;
그리고 cshtml으로 갑니다.
@model List<WebApplication1.Models.Document>
@{
Layout = null;
var member = ViewData["Member"] as WebApplication1.Models.Member;
}
@foreach(string s in ViewBag.Arr)
{
<div>@s</div>
}
< Layout >
레이아웃을 우리말로 한다면 '배치'입니다.
프로그래밍적으로 레이아웃은 반복되는 코드, 중복되는 코드를 다시 사용할 일 없게끔 하는 것 입니다.
@RenderBody() 라는 것과 입력했던 값이 대체 된다.
<개념정리>
1. ViewBag & ViewData: 이들은 컨트롤러에서 뷰로 데이터를 전달하는 데 사용합니다. ViewData: ViewData는 Key-Value 쌍의 딕셔너리로서, TempData와 유사하지만 요청이 끝날 때 소멸됩니다. ViewData는 동적 속성을 제공하지 않으며, 문자열을 키로 사용합니다. 데이터 형식을 지정해야 되기 때문에 형식 변환이 필요할 수 있습니다. ViewBag: ViewBag은 ViewData의 래퍼이며, 동적 속성을 제공하는 데 사용됩니다. ViewBag을 이용하면 코드가 더 짧아지며, 지정된 속성에 동적으로 액세스할 수 있습니다. 형식 변환 필요성이 줄어들지만, 코드 작성 시 덜 엄격하게 체크한다는 단점이 있습니다.
2. Razor: Razor는 ASP.NET의 바인딩 구문 중 하나로, C# 또는 VB코드를 HTML 문서에 삽입하여 웹 페이지를 동적으로 생성합니다. Razor 구문은 '@' 기호로 시작하며, 다음과 같은 형식을 가집니다. '@(표현식)', '@{ ... }' 등입니다. Razor는 서버 측 코드와 클라이언트 측 코드를 명확하게 구분하여 개발자가 코드를 쉽게 작성하고 유지할 수 있도록 지원합니다.
3. Layout: Layout은 ASP.NET에서 마스터 페이지와 같은 개념으로, 공통되는 페이지 요소를 재사용하고 중복을 줄이기 위한 방법입니다. 여러 뷰에서 공유할 수 있는 베이스 페이지를 설정하고, 각 뷰에 필요한 내용만 추가하여 효율적으로 페이지 구성을 관리할 수 있습니다. Layout 페이지는 _Layout.cshtml 파일로 저장되며, 각 뷰에서 '@{ Layout = "_Layout"; }'와 같은 코드로 그것을 참조할 수 있습니다.
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace LibraryApplication.Models
{
public class Book
{
[Key]
public int Book_U { get; set; }
[DisplayName("제목")]
public string Title { get; set;}
[DisplayName("저자")]
public string Writer { get; set; }
[DisplayName("요약")]
public string Summary { get; set; }
[DisplayName("출판사")]
public string Publisher { get; set; }
[DisplayName("출판일")]
public int Published_date { get; set; }
}
}
그후 Web.config에서 다음과 같은 코드를 추가한다.
<connectionStrings>
<add name ="DBCS" connectionString="server=MSSQL_SERVER_ID; database=Library; integrated security=SSPI" providerName="System.Data.SqlClient"/>
</connectionStrings>
그리고 Context라는 폴더 생성후 클래스 LibaryDb 생성
using LibraryApplication.Models;
using System.Data.Entity;
namespace LibraryApplication.Context
{
public class LibaryDb : DbContext
{
public LibaryDb():base("name=DBCS") { }
public DbSet<Book> Books { get; set; }
}
}