네트워크
전화를 이용한 사람 간의 통신
홍길동은 홍길순에게 전화를 걸기 위해 전화번호부에서 홍길순을 찾는다.홍길순의 전화번호가 013-1200-3001임을 알아낸다.전화기를 이용하여 013-1200-3001 번호를 눌러 홍길순과 통화한다.이 방법은 컴퓨터 간 통신에도 그대로 적용된다.
네트워크 어댑터를 이용한 컴퓨터 간의 통신

사용자 PC는 네이버에 접속하기로 했다.이때 사용자는 네이버의 도메인 네임이 www.naver.com인 것을 알고 DNS서버에 그것에 해당하는 IP주소를 요청한다.DNS서버는 내부 스토리지(DNS테이블)에서 www.naver.com의 IP주소를 찾고 사용자 PC에 전달한다.네트워크 어댑터는 대상 IP주소가 네이버에 해당하는 202.179.177.21에서 통신을 시작한다.컴퓨터 간 통신에서 서로의 주소(address)을 아는 것과 함께 주요한 것이 어떤 절차를 거쳐서 통신을 주고받을지에 대한 규칙을 정하는 것이다.이를 프로토콜(protocol)라고 하는데 현재 인터넷에서 가장 많이 이용되는 프로토콜이 TCP/IP(Transmmission ontrol Protocol/Internet Protocol)이다.System.Net.IP.Address현재 널리 쓰이는 TCP/IP의 IP(Internet Protocol)은 4번째 버전에 해당하는 기술이며 이를 줄여서 IPv4(Internet Protocol version 4)이라고 한다.IP주소가 4바이트다는 점은 표현할 수 수의 범위가 약 42억에 제한되는 것을 뜻한다.국제 인터넷 번호 관리 기관(IANA:Internet Assigned Numbers Authority)는 2011년 초에 모든 IP주소가 고갈했다고 발표. 이에 대비한 새로운 IP통신 표준이 출렁이고 있는 상태여서 개정된 버전치에 맞고 IPv6(Internet Protocol version 6으로 알려졌다.IPv6주소 용량은 합계 128라이트로 3.4*10^{38}에 해당하는 천문학적인 어드레스 영역을 가지고 있어 IP주소의 걱정은 없다고 본다.공용 IP과 개인 IP
공용 IP와 개인 IP

그림으로 사내 PC에 할당된 192.168.0.2~192.168.0.4라는 주소가 개인 IP.PrivateIP라고도 불리며, 외부로부터 액세스 할 수 없다.사내 PC간에는 서로의 개인 IP주소를 알고 있으니 통신하는 데 문제가 없다.공용 IP(Public IP)이 설정된 라우터를 통해서 인터넷에 접속되기 때문에 사내 PC에서는 외부의 공용 IP가 부여된 기기에 자유롭게 접속 가능
가정의 인터넷 접속 구조
인터넷 서비스 업체(ISP:Internet Serice Provider)에서는 미리 대량의 공용 IP를 보유한 상태.집의 컴퓨터에 할당된 IP는 공용기이지만, 컴퓨터를 오프로 하면 해당 IP는 ISP업체에 회수되어 재기동하면 또 다른 이용 가능한 공용 IP가 배정된다.만약 집에서 AP(Access Point) 같은 공유 기기를 사용하는 경우, ISP에서 제공되는 공용 IP는 AP로 배정 받아 AP접속된 다른 장비는 모두 개인 IP를 갖게 된다.공용 IP가 모두 소진하고 제한된 수의 장비에만 할당되지만 이처럼 다양한 내부 IP활용의 덕분에 IPv6의 도움 없이 IPv4가 여전히 살아남는다
IP 주소만으로 통신

IP 주소만으로 통신해야 하는 제약을 극복하기 위해 TCP/IP 는 “포트”라고 하는 개념을 추가.포트는 단순하게 0~65535 범위에 해당하는 값이므로 단순히 ushort로 표현IP와 포트가 함께 적용된 경우포토 번호 중에는 이미 용도에 대해서 세계적으로 합의한 것도 있다.21번 포트는 FTP서버, 25번 포트는 SMTP서버 80번 포트는 웹 서버와 같이 10~24번까지 예약되어 있다.원하면 만든 프로그램을 25번 포트로 써도 좋지만 굳이 충돌의 위험을 감수할 필요는 없다.통상 1025~65535범위의 포트 번호를 경정하는 것을 권장.System.Net.Dns유저로부터 “http://www.microsof.com”라고 하는 문자열을 입력되면 TCP/IP통신을 실시하기 위해서 반드시 대응하는 IP주소로 변경해야 한다.이때 사용할 방법이 DNS타입이다.IPHostEntry엔트리=Dns.GetHostEntry(myComputer);각(엔트리 내의 IPAddress ipAddress). 주소록){콘솔.WriteLine(ipAddress;글 회선).주소 패밀리+”:”+ipAddress);}GetHostEntry 정적 메서드는 도메인 이름을 입력하면 시스템에 설정된 도메인 네이밍 서버(DNS)에서 해당 이름의 IP를 조회합니다.2개 이상의 IP가 할당됩니다.현재 컴퓨터에 할당된 IP 주소를 출력합니다.static void Main(string[]args){string myComputer=Dns를 지정합니다.GetHostName();콘솔.WriteLine(“+myComputer”);IPHostEntry엔트리=Dns.GetHostEntry(myComputer);각(엔트리 내의 IPAddress ipAddress). 주소록){콘솔.WriteLine(ipAddress;글 회선).주소 패밀리+”:”+ipAddress);}static void Main(string[] args) {string myComputer = Dns 를 지정합니다.GetHostName(); 콘솔.WriteLine(” + myComputer”); IPHostEntry エントリ = = Dns。GetHostEntry(myComputer); 각(엔트리내의 IPAddress ipAddress). 주소 리스트){콘솔.WriteLine(ipAddress; 기입 회선)주소 패밀리 + “:” + ipAddress); }출력된 주소가 10.0~10.255.255.175, 172.16.0~172.3~125.255, 192.168,0~192.168,255의 범위에 포함된다면 개인 IP이고, 그 외의 경우 공용 IP일 가능성이 높아요.도메인 이름과 IP 관계도메인 이름을 사용할 때의 단 하나의 단점이라면 DNS에서 IP주소를 조회해야 하기 때문에 그만큼 속도가 떨어진다는 점이다.운영 체계에는 내부적으로 한번 조회된 도메인 이름과 IP주소는 일정 시간 보존하는 기능이 있다.다음 같은 DNS조회 요청이 오면, 서버와의 통신 없이 미리 저장된 IP주소를 즉시 반환함으로써 속도 향상도메인 이름 부하 분산 롤한 도메인 이름에 N개의 IP가 묶여 있을 경우 일종의 부하 분산(load balance) 역할을 하기도 한다. TCP, UDP 방식의 차이TCP는 3way hand shake(Hardward)를 통하여 접속 유무, 순서, 송신 보장하지만 속도는 더딘 MMORPG, RPG UDP는 그냥 sendTo(), recvfrom()함수만 있으면 데이터를 교환했지만 TCP는 데이터를 교환하기 전에 “접속”과정을 먼저 해야 한다.이를 보고연결 지향형(커넥션 oriented)이라고 한다.(Stateful특징)TCP는 일대일만 가능세션은 1개의 클라이언트와 1개의 서버 사이에만 존재 매번 접점 정보를 알기 위한 IPEndPoint인자를 전달할 필요는 없다.연결성을 연결한 후에 데이터를 교환할 수 있다는 불편이 있지만 대신 보낸 데이터가 받는 측에서 정확히 모두 도착하는 것을 보장한다.이런 특징 때문에 프로그램의 대부분이 TCP를 활용한다.신뢰성 Send메서드를 통해서 수신 측에 데이터가 전달되면 수신 측은 내부적으로 그에 대한 확인(ACK)신호를 송신 측에 전달한다.그러므로 TCP통신은 데이터가 수신 측에 정상적으로 전달됐는지를 알 수 있으며 이 과정에서 ACK신호가 오지 않으면 자동으로 데이터를 재전송함으로써 신뢰성을 확보한다.TCP신뢰성을 보장하는 방법:https://blog.naver.com/ya3344/222788749616세그먼트 응답이 올 때까지 송신스트림 중심의 TCP는 메시지 형태가 아니고 스트림 형태라는 점이다.보내는 측에서 a, bb, cc, ddd를 전송하면 받아들이는 측에서도 a, bb, ccc, ddd뿐만 아니라 abbcccdd에서 받을 수도 있다.즉, 데이터를 묶거나 나눌 수 있다.1회 Send메서드가 실행되었음에도 불구하고 수신 측은 계속 Receive메서드를 호출함으로써 모든 데이터를 받을 수 있다.이처럼 메시지 경계를 갖지 않고 전달되는 것을 스트리밍 방식으로 알려졌다.순서 보장 데이터를 송신 차례로 수신 측에 전달된다.예를 들어 3회 Send메서드가 호출된 가 모퉁이 100,105,102바이트가 전송되는 경우 수신 측의 최초의 Receive메서드는 100바이트에 해당하는 데이터를 먼저 스트림 방식으로 수신하게 된다.TCP의 특징의 중간에 데이터가 소멸하지 않고 전송된다.전송 뒤에 데이터가 수신된다.3Way handshak기법으로 정보가 전송 전송되는 데이터의 경계가 없다.(스트림 형태)TCP소켓은 경계가 존재하지 않고 Read함수 호출에서 읽는 데이터의 양보다 많은 데이터가 수신되면 버퍼가 가득 될 수 있다.connect실패의 경우 즉각 에러의 경우 일정 시간이 경과했을 경우, 오류, syn을 송신한 것에 금방 실패를 주는 경우(방화벽이 막힌 경우)일정 시간이 경과했을 경우, 에러는 3 way handshake대기 실패 서버에서 Accept이 하지 못하는 일은 클라이언트는 모른다 backlog큐가 가득 될 때까지 클라이언트 커넥트 성공 이후 실패 클라이언트 측에서 다이내믹 포트 대역이 부족하면 커넥트 실패가 가능하다.TCP헤더 구분경계 TCP데이터는 절단 또는 굳어질 수 있 끊겼는지 판단이 가능해야 한다.발신인은 항상 고정 길이 데이터를 보내는(비 현실적)EOF를 남기는 등.(비 현실적)헤더 정보에 길이 정보를 전달.(추천)UDP의 경우는 길이를 보낼 필요가 없다이유는 길이가 완성하기 때문.맨 앞의 1byte을 우리의 패킷인지 확인하는 데 사용하는 것도 있다.checksum은 패킷 변조를 확인하기 위해서 사용하지만 checksum을 사용한다고 패킷 변조를 모두 막을 수 없다.네트워크 구조체 패딩 문제 패딩은 불필요한 데이터 전송의 추가 트래픽이 증가한다.절감 기준이 클럽 서버가 다르다.pragma pack을 사용하면 cpu성능이 떨어지는 것도 있지만, 패킷을 보내면서 해당 캐시 크기 재봉틀에 되는 것이 별로 없다.(send, recv의 역할은 패킷을 단순하게 보내는 것이기 때문에 데이터를 쓰는 연산을 별로 하지 않다.)TCP소켓TCP 서버 소켓Bind 단계까지는 UDP 서버 소켓을 사용하는 범버와 유사하다.TCP 서버측 소켓 구현private static void serverFunc(object obj){(Socket srvSocket=new Socket(Address Family)를 사용하고 있습니다.InterNetwork, 소켓 유형.스트림 프로토콜타입 Tcp){IPEndPoint endPoint=newIPEndPoint(IP주소).임의, 11200).srvSocket.바인드(엔드 포인트), srvSocket.listen(10);while(true){Socket clntSocket=srvSocket}. accept();byte[]recvBytes=new아르바이트[socket];int nRecv=clntSocket.수신(recvBytes).string txt=Encoding입니다.UTF8.GetString(recvBytes, 0, nRecv);byte[]sendBytes=인코딩. UTF8.GetBytes(“Hello:”+txt);clntSocket. 송신(sendBytes);clntSocket.감();}}UDP와 비교하고 Connect단계를 추가합니다.Accpet에 반환된 소켓은 클라이언트 측 TCP소켓과 1대 1대응하기 때문에 Send/Receive메서드를 호출할 때 굳이 접점 정보를 알기 위한 IPEndPoint인자를 전달할 필요는 없습니다.ex)TCP클라이언트 측 소켓을 구현합니다private static void clientFunc(object obj){Socket socket=newSocket(Address Family).InterNetwork, 소켓 유형.스트림 프로토콜타입 Tcp).EndPoint서버 EP=new IP EndPoint(IP주소). 루프 백(11200);소켓. Connect(서버 EP);byte[]buf=인코딩. UTF8.GetBytes(DateTime).Now.ToString();소켓. send(buf);byte[]recvBytes=new아르바이트[socket];int nRecv=socket.수신(recvBytes).string txt=Encoding입니다.UTF8.GetString(recvBytes, 0, nRecv);콘솔.WriteLine(txt);소켓. Close();콘솔. 글 행(“)TCP클라이언트 소켓: 닫습니다”;}TCP클라이언트 측에서 Connect를 호출 시점에서 TCP서버는 반드시 Listen을 호출한 상태이어야 한다.그렇지 않으면 TCP클라이언트가 Connect호출은 예외를 일으키고 실패하고 만다.TCP서버의 개선 다중 스레드와 비 동기 통신 소켓 통신에 사용되는 모든 메소드가 기본적으로 동기 호출인 데에 문제가 있다.I/O가 완료될 때까지 Send/Receive메서드를 호출한 스레드는 차단되므로 서버 측에서 Accept를 신속히 처리할 수 없다는 문제가 발생한다.이런 문제를 해결하기 위해서, 서버 소켓이 Accept로 반환된 클라이언트 처리를 별도의 스레드에 맡기고 처리할 방법이 있다.ex)다중 스레드와 비 동기 통신TCP 클라이언트 측에서 Connect를 호출하는 시점에서 TCP 서버는 반드시 Listen을 호출한 상태여야 한다. 그렇지 않으면 TCP 클라이언트가 Connect 호출은 예외를 일으켜 실패하고 만다. TCP 서버 개선 – 다중 스레드와 비동기 통신 소켓 통신에 사용되는 모든 메서드가 기본적으로 동기 호출임에 문제가 있다.I/O가 완료될 때까지 Send/Receive 메서드를 호출한 스레드는 차단되므로 서버 측에서 Accept를 신속하게 처리할 수 없는 문제가 발생한다.이러한 문제를 해결하기 위하여 서버 소켓이 Accept로 반환된 클라이언트의 처리를 별도의 스레드에 맡겨 처리하는 방법이 있다.ex)멀티 스레드와 비동기 통신Begin Receive→ End Receive→ Begin Send→ End Send로 이어지는 비동기 호출 패턴.비동기로 동작하므로 즉시 제어가 반환되고 while루프의 처음으로 돌아가서 Accpe호출을 계속 실행 별도의 쓰레드를 생성하지 않아도 다른 클라이언트의 접속을 지연(day)없이 받아 처리 비동기 호출로 바뀌어 실장이 지나치게 복잡하게 되기 때문에 고성능 TCP서버를 구현하지 않으면 비동기 호출을 이용하기보다는 스레드와 클라이언트가 일대일로 대응하는 형식는 방식을 선호하는※ICP정리 htps://blog.naver.com/ya3344/222736452677IOCP 리 CraeteIoCompletionPort – 초 IOCP를 동시 스레드 수 NUL※OVERLAPPED IO 리https blog.naver.com/ya3344/222734592972 。OVERLAPPED IO 정리 OVERLAPPED IO 개념 Non Blocking과 비동기 I/O 처리가 합쳐진 개념으로 기존에 있던 No… blog.naver.com※ 네트워크 모델별 특징 https://blog.naver.com/ya3344/222753597540네트워크 모델별 특징 Select 특징 다양한 운영체제 시스템에서 모두 지원. 싱글 스레드에서의 멀티 소켓 처리(I/O 발생 유무)에 대응… blog.naver.com※ 소켓옵션 https://blog.naver.com/ya3344/222452432089소켓 옵션 브로드캐스팅 – 브로드캐스팅 주소는 라우터로 진행할 수 없다. (나와 큰 대역(미국)에 브로드캐스팅… blog.naver.com소켓 옵션 브로드캐스팅 – 브로드캐스팅 주소는 라우터로 진행할 수 없다. (나와 큰 대역(미국)에 브로드캐스팅… blog.naver.comUDP UDP는 User Datagram Protocol의 약어이며 사용자가 정의한 데이터그램을 상대방에게 송신할 수 있도록 한 통신 규약이다.비연결성 연결 여부, 순서, 송신을 보장하지 않는다.그러나 속도가 빠르기 때문에 Reliable UDP를 만들어 신뢰성을 보장하고 사용하는 경우가 많다(Reliable UDP는 매우 높은 기술력이 필요)LOL, AOS오버 워치 슈팅 게임, 격투기(Reliable UDP)TCP는 신뢰성 보장을 Hardward로, Reliable UDP는 Software에서 신뢰성을 보장한다.메시지 중심의 송신 측에서 한번의 SendTo메서드 호출에 1000바이트의 데이터를 송신했을 경우, 수신 측에서도 ReciveFrom메서드를 한번 불러냈을 때 100바이트를 받는다.즉, SendTo에 전달된 64KB이내의 바이트 배열은 상대로 정상에 보내는 것에 성공하면 ReceiveFrom메서드에서는 그 바이트 배열 데이터를 그냥 한번 받을 수 있다.(메시지 경계가 지켜진다) 보낼 측에서 a, bb, ccc, ddd를 보내면 받는 측에서도 a, bb, ccc, dddd형태로 받기가 보장된다.즉, 데이터의 일부가 굳거나 찢어지지 않는다.신뢰성 연결 순서 없이 UDP는 패킷 유실 현상이 발생할 수 있다.a, bb, ccc, dddd중 1개 이상 못 받거나 같은 데이터그램을 2회 이상 받을 가능성이 있고, 송신 순과 달리 데이터그램을 받을 수도 있다.데이터 그램의 내용이 손상되지 않는 것이다.( 깨지기는 매우 드물다.)UDP의 사용 사례를 받는 측에서 데이터그램의 유실이나 순서의 역전, 혹은 중복 수신 현상이 발생해도 좋을 때만 UDP를 사용하는 것이 바람직하다.예를 들면, 동영상이나 음성 데이터를 송신할 때 좋다.네트워크 게임에서는 캐릭터가 이동할 때마다 계속 보내는 이동 정보를 보낼 때 UDP를 쓰기도 한다.비록 도중에 데이터그램의 유실이 생겨도, 이어 도착하는 캐릭터 이동 정보가 보완하고 주기 때문이다.UDP의 특징 UDP의 또 하나의 특징은 크다통신을 할 수 있다는 점이다.상대의 종점만 알면 우편을 보내게 보내면 된다.데이터를 송신할 때 MTU1500Byte로 나누어 하나라도 유실되면 모두 패기다.UDP는 L4로 자르지 않아 1500Byte이상이면 2번째 패킷으로부터 UDP헤더가 붙지 않아 1개가 끊어졌다면 모두 버려야 한다.반대로 TCP는 L4로 자르는 매번 헤더가 붙기 때문에 절단된 패킷만 재전송하면 된다.TCP는 ESTABLISHED가 송신 IP와 통신해야 데이터 전송이 가능하지만 UDP는 포트만 열고 있으면 누구나 데이터를 전송할 수 있다.하나의 포트에서 수많은 사용자와 통신해야 한다.UDP소켓 하나로 통신한다.(TCP는 클라이언트인당 소켓이 생긴다.)동기 입출력의 경우에 이더넷 1개에 들어가기 때문에 소켓이 1개에서도 복수에서도 속도 차이는 없다.overlaapedio의 경우 비동기 소켓이어서 소켓이 적다고 불리하다.소켓 단위로 관리하기 때문에 이런 경우 UDP에서도 포트를 복수 사용할 수도 있다.UDP를 사용하는 이유의 하나는 최근 모바일 게임이 접속이라는 개념이 버려지고 있다.Lte통신 모바일의 잦은 접속 끊어져, ip이 변경되는 이유 등으로 클라이언트의 첫 sendto의 때에 바인딩 한다.(다음 쓸 때는 바뀌지 않는다.(재사용)udp는 메시지가 부서지고 맞거나 하는 부분을 볼 필요는 없다하나의 메시지가 그대로 옴 UDP소켓 서버 컴퓨터에는 복수의 어댑터와 복수의 IP이 묶인 수 있다.즉, 컴퓨터와 어댑터는 1:N관 게이지인 어댑터와 IP주소도 1:N관계이다.클라이언트 소켓은 데이터가 송신해야 할 대상을 지정하기 위해서 접점 정보(IP주소와 포트)이 필요하다.서버 소켓은 컴퓨터에 할당된 IP주소 중 어느 쪽과 연결되는지를 결정해야 하며 이 과정을 바인딩이라고 한다.소켓이 특정 IP와 항만에 묶으면 바인딩이 성공했다고 볼 수 있다.일단 이렇게 바인딩 되면 다른 소켓에서는 절대로 같은 접점 정보로 바인딩 할 수 없다.ex)UDP소켓:서버 측 바인딩private static void serverFunc(object obj){Socket socket=newSocket(Address Family).InterNetwork, 소켓 유형.Dgram프로토콜타입. Upd);IPAddress ipAddress=GetCurrentIPAddress();if(ipAddress==null){콘솔. 글 행(“)IPv4(“”);return;}IPEndPoint endPoint=newIPEndPoint(ipAddress, 10200);소켓. 바인드(endPoint);}//개인 정적 IP주소 GetCurrentIPAddress(){IPAddress[]addrs=Dns.GetHostEntry(Dns.GetHostName().AddressList;for each(IPAddress ipAddr in addrs){if(ipAddr.Address Family==주소 패밀리.InterNetwork){return ipAddr;}}는 null를 갚겠습니다;}private static void serverFunc(object obj){Socket socket = newSocket(Address Family)。Inter Network, 소켓 유형.Dgram, 프로토콜 타입.Upd); IPAddress ipAddress = GetCurrentIPAddress();if (ipAddress == null) { 콘솔.쓰기 행 (“) IPv4 (“); return; }IPEndPoint endPoint = newIPEndPoint(ipAddress、10200); 소켓.바인드(endPoint);}// 프라이빗 스태틱 IP주소GetCurrentIPAddress(){IPAddress[] addrs = Dns。GetHostEntry(Dns。GetHostName()。AddressList;for each (IPAddress ipAddr in addrs) {if (ipAddr。Address Family == 주소 패밀리.InterNetwork) {return ipAddr;} } 은 null을 반환합니다;}멀티 IP에서의 소켓 바인딩입니다.사용자 1컴퓨터에서 UDP소켓 서버를 실행하면 GetCurrentIPAddress가 10.10.10.200또는 60.20.10.150의 하나를 갚겠습니다.만약 10.10.10.200을 반환했다고 가정하면 UDP소켓 서버는 접점이 10.10.10.200:10200에 바인딩.이처럼 특정 IP에 묶이면 해당 IP를 소유하는 네트워크 어댑터와 연결된 PC는 사용자 2는 사용자 1와 통신할 수 있지만 별도의 네트워크 어댑터와 연결된 사용자 3은 통신할 수 없는.이런 문제를 해결하기 위하여 각 IP에 바인딩 할 수 있도록 여러 소켓을 생성할 수도 있다.이런 식의 해결책은 코드 작성을 성가시게 한다는 단점이 있다.이 때 쓰는 특별한 주소가 “0.0.0.0”이다.(Any)Socket socket=new Socket(주소 패밀리).InterNetwork, 소켓 유형.Dgram프로토콜타입. Udp);//IPAddress ipAddress=IP주소.Parse(“0.0.0.0”);//IPEndPoint endPoint=newIPEndPoint(ipAddress, 10200);IP EndPoint endPoint=newIPEndPoint(IP주소).(임의, 10200);소켓. 바인드(엔드 포인트);컴퓨터에 할당된 모든 IP 주소에 바인딩되므로 사용자 2, 사용자 3 모두에서 액세스할 수 있습니다.UDP 예제 프로그램입니다.byte[]recvBytes=new아르바이트[키워드];엔드 포인트 클라이언트 EP=new IP EndPoint(IP주소). 없음 0);int nRecv=srvSocket.ReceiveFrom(recvBytes참조 클라이언트)EP);ReciveFrom의 최초의 인자는 클라이언트 측에서 보낸 데이터가 포함되는 버퍼를 준비 주고, 2번째 인자인 EndPoint는 ref에 전달되지만 입력되는 대로 정보는 의미가 없다.데이터가 수신되면 해당 데이터를 송신 측의 접점 정보를 담고 반환하는 역할을 한다.string txt=인코딩. UTF8.GetString(recvBytes, 0, nRecv);byte[]sendBytes=인코딩. UTF8.GetBytes(“Hello:”+txt);srvSocket.SendTo(sendBytes클라이언트)EP);”HELLO:”을 달아 재전송하는 것이므로, 가공 후 Socket타입의 SendTo메서드를 사용하는 코드를 추가합니다.SendTo메서드의 첫번째의 인자로서 송신하는 데이터를 포함한 바이트 배열을 전달하면 되죠.ReceiveFrom의 2번째 인자로 받은 EndPoint객체를 그대로 전달합니다.ex)UDP서버 측 소켓을 구현합니다private static void serverFunc(object obj){Socket srvSocket=newSocket(AddressFamily).InterNetwork, 소켓 유형.Dgram프로토콜타입. Upd);IPEndPoint endPoint=newIPEndPoint(IP주소).임의, 10200).srvSocket.Bind(endPoint);byte[]recvBytes=new byte[subject];엔드 포인트 클라이언트 EP=new IP EndPoint(IP주소). 없음 0);while(true){intnRecv=srvSocket}.ReceiveFrom(recvBytes참조 클라이언트)EP);string txt=인코딩. UTF8.GetString(recvBytes, 0, nRecv);byte[]sendBytes=인코딩. UTF8.GetBytes(“Hello:”+txt);srvSocket.SendTo(sendBytes클라이언트)EP);}(UDP클라이언트소켓private static void clientFunc(object obj){Socket clntSocket=newSocket(AddressFamily).InterNetwork, 소켓 유형.Dgram프로토콜타입. Udp).EndPoint서버 EP=new IP EndPoint(IP주소). 루프 백, 10200);EndPoint송신 측 EP=new IP EndPoint(IP주소). 없음 0). int nTimes=5;while(nTimes->0){byte[]buf=Encoding.UTF8.GetBytes(DateTime).Now.ToString();clntSocket.SendTo(buf, 서버 EP), byte[]recvBytes=new byte[socket], intnRecv=clntSocket.ReceiveFrom(recvBytes참조원)EP);string txt=인코딩. UTF8.GetString(recvBytes, 0, nRecv);콘솔. 글 행(txt);스레드. 슬리프(1000);}clntSocket.Close();콘솔.WriteLine(“UDP클라이언트 소켓: 닫습니다”;}복수의 UDP 클라이언트를 실행합니다.for(inti=0;i<3;i++){스레드 클라이언트 Thread=newThread(clientFunc);클라이언트 쓰레드.IsBackground=true;클라이언트 쓰레드.시작();}for (inti = 0; i < 3; i++){스레드 클라이언트 Thread = newThread(clientFunc); 클라이언트 스레드.IsBackground = true; 클라이언트 스레드.개시();}3개의 스레드에 실행되는 UDP 클라이언트입니다.TCP, UDP공통점 UDP는 신뢰할 수 없는 데이터 전송을 하기 때문에 데이터 에러를 체크하지 않다고 생각해서는 안 된다.UDP와 TCP는 모두 체크 섬을 이용하여 데이터 오류를 체크한다.다만 차이는 TCP는 데이터 재송신과 데이터 순서 유지를 위한 작업을 실시하지만, UDP은 재송신과 데이터 순서 유지를 위한 작업을 하지 않고 오류가 있으면 그대로 삭제한다.UDP에서 신뢰성 있는 데이터 전송을 하려면 데이터 재전송+데이터 순서 유지, 두 기능을 반드시 구현해야 한다.또 속도가 다른 컴퓨터에서 실행되는 어플리케이션이 UDP를 이용하고 대량의 데이터를 교환하려면 흐름 제어 기능을 구현해야 한다.UDP와 TCP는 모두 인터넷 프로토콜(IP위에서 작동하고 IP이 OSI모델의 계층 3에 있어 UDP와 TCP는 계층 4에 위치한다.HTTP통신 인터넷 익스플로러, 크롬/등의 브라우저의 역할은 “웹 서버”측에 “HTTP프로토콜”을 사용하여 데이터를 요청하여 수신하고 화면에 표시하는 것이다.HTTP통신은 TCP서버/클라이언트의 한 예다.즉, 웹 서버는 TCP서버인 웹 브라우저는 TCP클라이언트이다.일반적으로 HTTP서버는 80포토를 사용할 약속되어 있다.ex)TCP소켓을 이용한 HTTP통신static void Main(string[]args){Socket socket=newSocket(Address Family).InterNetwork, 소켓 유형.스트림 프로토콜타입 Tcp)IPAddress ipAddr=Dns입니다.GetHostEntry(“www.naver.com”).AddressList[0];EndPoint서버 EP=newIPEndPoint(ipAddr, 80);소켓. Connect(serverEP);string request=”GET/HTTP/1.0\r\nHost:www.naver.com\r\n\r\n”;byte[]sendBuffer=Encoding.UTF8.GetBytes(request);//HTTP소켓.Send(sendBuffer);//HTTP청에서달에게 보내는답버 MemoryStreams=newMemoryStream();while(true){byte[]rcvBuffer=new아르바이트[4096];intnRecv=소켓.Receive(rcvBuffer);if(nRecv==0){//서버측에 을상.}ms.write(rcvBuffer, 0, nRecv);}소켓.Close();string response=인코딩. UTF8.GetString(ms.).GetBuffer(), 0,(int)ms.길이);콘솔.WriteLine(response);//HTML파일을 작성합니다.WriteAllText(“naverpage.html”, response);}static void Main(string[] args){Socket socket = newSocket(Address Family)。Inter Network, 소켓 유형.스트림, 프로토콜 타입. Tcp) IPAddress ipAddr = Dns 입니다.GetHostEntry(“www.naver.com “)。AddressList[0]; EndPoint サーバ EP = newIPEndPoint(ipAddr、80); ソケット。Connect(serverEP); string request = = “GET / HTTP/1.0\r\nHost: www.naver.com \r\n\r\n”; byte[] sendBuffer = Encoding。UTF8.GetBytes(request);/HTTP 소켓.Send(sendBuffer); // HTTP 청에서 달에게 보내는 답버 MemoryStreams=newMemoryStream(); while (true) {byte[] rcvBuffer=new바이트[4096]; intnRecv=소켓.Receive(rcvBuffer);if (nRecv == 0) 0) { // 서버 측에 을상 \} ms。write(rcvBuffer, 0, nRecv); } 소켓.Close(); string response = 인코딩. UTF8. GetString(ms.).GetBuffer(), 0, (int)ms。길이); 콘솔.WriteLine(response); // HTML 파일을 만듭니다.WriteAllText(“naverpage.html”, response);}IE와 크롬 같은 실제 웹 브라우저는 이렇게 받은 응답으로 개행 문자 2개가 연속해서 나온 뒤 내용을 분석하여 화면에 표시하는 역할을 한다.HTTP프로토콜은 요청과 응답에서 이같이 2개의 개항 문자를 구분자로서 HTTP헤더와 본문의 내용을 구성한다.ex)TCP소켓을 탑재한 HTTP서버static void Main(string[]args){(Socket srvSocket=new Socket(Address Family)를 사용하고 있습니다.InterNetwork, 소켓 유형.스트림 프로토콜타입 Tcp){콘솔.WriteLine(“http://localhost:8000″);IPEndPoint endPoint=newIPEndPoint(IP주소).임의, 8000).srvSocket.바인드(엔드 포인트), srvSocket.listen(10);while(true){Socket clntSocket=srvSocket}.Accept();ThreadPool.QueueUserWorkItem(httpProcess)Func, clntSocket);}}}private static void httpProcessFunc(object state){소켓=소켓의 상태;byte[]reqBuf=새로운 아르바이트[4096];소켓. Receive(reqBuf);string header=”HTTP/1.0 200 OK\nContent-Type:text/module;charset=UTF-8\r\n\r\n”;string body=”<flash><body><mark>스 HTML</mark>웹 이</body></flash>”;byte[]respBuf=Encoding입니다.UTF8.GetBytes(헤더+보디);소켓. send(respBuf);소켓. 감();}System.Net。HttpWebRequest(Web 要求)static void Main(string[]args){//Http WebRequest타입은 내부적으로 TCP소켓을 생성하고 Http WebRequest req=WebRequest.Create(“http://www.naver.com”)as Http WebRequest;//GetResponse호출 단계에서 지정된 웹 서버로 HTTP리퀘스트를 송신하고 응답을 받는다.HttpWebResponse resp=req.GetResponse()as HttpWebResponse;//응답 내용을 포함한 Stream에서 문자열을 갚고 출력한다.using(StreamReader sr=new StreamReader(resp.GetResponseStream(){string responseText=sr.ReadToEnd();Console.WriteLine(responseText);File.WriteAllText(“naverpage.html”, responseText);}}HTTP헤더 영역이 제거된 순수하게 HTTP본문만 포함됐다.HttpWebRequest객체는 HTTP통신과 관련된 요청/응답 데이터를 적절히 해석하는 역할까지 대행하기 때문에 TCP소켓을 직접 사용하여 통신해야 하는 불편이 줄어든다.System.Net.WebClientstatic void Main(string[]args){//WebClient타에서 HttpWebRequest체에게보내는 답를 WebClient wc=newWebClient();string responseText=wc.DownloadString(“http://www.naver.com”);콘솔.WriteLine(responseText);}HttpWebRequest도 복잡하게 느끼면 더 기능을 추상화된 WebClient유형을 고려하고 HTTP통신을 이용해서 파일을 올릴 수 있는 UploadFile, 반대로 파일을 다운로드하는 DownloadFile 같은 유용한 메소드가 제공된다.