안녕하세요. 명월입니다.
이번 포스팅에서는 C#으로 웹 서버를 개발하는 것에 대해 알아보도록 하겠습니다. 웹 서버는 이미 아파치와 IIS 등등 좋은 웹서버는 많이 있습니다. 그래서 따로 이렇게 개발 안해도 무료로 좋은 웹서버가 많습니다. 그래도 웹 서버를 연습으로 만들어 보면 웹서버가 어떻게 이루어 지는 지 알 수 있고, 웹 서버가 아니더라도 다른 서버 프로그램을 개발할 때 응용이 가능합니다.
웹 서버를 만들기 전에 웹 프로토콜을 알아야 하는데 예전에 소개한 포스팅이 있습니다.
바로가기 - 프로토콜이란
먼저 아파치 서버를 이용해서 웹 서버에 접속하는 테스트 클라이언트 프로그램을 만들겠습니다.
Copy! [소스 보기] using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; namespace blog_20121015 { class Program { static void Main(string[] args) { new Program(); Console.ReadLine(); } public Program() { IPHostEntry host = Dns.Resolve("nowonbun.tistory.com"); IPAddress IP = host.AddressList[0]; Console.WriteLine(IP.ToString()); IPEndPoint ipep = new IPEndPoint(IP, 80); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.Connect(ipep); String Send = @"GET / HTTP/1.1\r\n Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n Accept-Language: ko\r\n User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; EmbeddedWB 14.52 from: http://www.bsalsa.com/ EmbeddedWB 14.52; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E; InfoPath.2)\r\n Accept-Encoding: gzip, deflate\r\n Host: 127.0.0.1\r\n Connection: Keep-Alive\r\n"; client.Send(Encoding.Default.GetBytes(Send)); client.Send(Encoding.Default.GetBytes("\r\n")); client.Send(Encoding.Default.GetBytes("\r\n")); byte[] _data = new byte[4096]; client.Receive(_data); client.Close(); Console.WriteLine(Encoding.Default.GetString(_data)); } } }
String Send 에 있는 부분에 HTTP 프로토콜 규약에 맞추어 Send를 보내는 부분 입니다.
위 결과 화면은 비록 400 Bad Request 라고 응답이 호출 되었지만 분명 tistory 에서는 프로토콜에 맞게 응신이 왔습니다. (Tistory 는 Apache 를 쓰는 군요. ㅎㅎㅎ)
여기까지 참고 소스 첨부하겠습니다.
첨부 파일 - blog_20121015.zip
여기 까지 됐으면 반대로 서버를 만들어 보도록 하겠습니다.
Copy! [소스 보기] using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.IO; namespace Test20121011 { class Program { static void Main(string[] args) { new Program(); } public Program() { IPEndPoint ipep = new IPEndPoint(IPAddress.Any,9999); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server.Bind(ipep); server.Listen(20); while (true) { Socket client = server.Accept(); try { String file = Recieve(client); FileInfo FI = new FileInfo(file); client.Send(Header(client, FI)); } finally { client.Close(); } } } public String Recieve(Socket client) { String _data_str = ""; byte[] _data = new byte[4096]; client.Receive(_data); Console.WriteLine(Encoding.Default.GetString(_data).Trim('\0')); String[] _buf = Encoding.Default.GetString(_data).Split("\r\n".ToCharArray()); if (_buf[0].IndexOf("GET") != -1) { _data_str = _buf[0].Replace("GET ", "").Replace("HTTP/1.1", "").Trim(); } else { _data_str = _buf[0].Replace("POST ", "").Replace("HTTP/1.1", "").Trim(); } if (_data_str.Trim() == "/") { _data_str += "index.html"; } int pos = _data_str.IndexOf("?"); if (pos > 0) { _data_str = _data_str.Remove(pos); } return "web"+_data_str; } public byte[] Header(Socket client,FileInfo FI) { byte[] _data2 = new byte[FI.Length]; try { FileStream FS = new FileStream(FI.FullName, FileMode.Open, FileAccess.Read); FS.Read(_data2, 0, _data2.Length); FS.Close(); String _buf = "HTTP/1.0 200 ok\r\n"; _buf += "Data: " + FI.CreationTime.ToString() + "\r\n"; _buf += "server: Myung server\r\n"; _buf += "Content-Length: " + _data2.Length.ToString() + "\r\n"; _buf += "content-type:text/html\r\n"; _buf += "\r\n"; client.Send(Encoding.Default.GetBytes(_buf)); } catch { String _buf = "HTTP/1.0 100 BedRequest ok\r\n"; _buf += "server: Myung server\r\n"; _buf += "content-type:text/html\r\n"; _buf += "\r\n"; client.Send(Encoding.Default.GetBytes(_buf)); _data2 = Encoding.Default.GetBytes("Bed Request"); } return _data2; } } }
위 소스에서 보면 요청이 오면 index.html 파일을 전송하는 것으로 만들었습니다.
그러면 index.html 를 만들어 보도록하겠습니다.
실제 웹서버처럼 이미지도 넣어보고 marquee 태그도 넣어보고 js도 넣어 보았습니다.
그럼 서버를 올려보도록 하겠습니다.
실제 서버처럼 작동을 합니다. 물론 서버스크립트를 붙히지 않아 html 밖에 되지는 않겠지만 이 정도면 기본적인 웹서버 기능은 작동 하겠습니다.
( 사실 프로토콜의 개념을 함께 설명하려고 했으나 너무 코드위주의 설명이 되어버렸습니다. 그러나 한번 따라서 코딩해보면 프로토콜 개념이 한번에 잡히니 한번 따라 코딩해 보시길 추천합니다.)
참조 파일 : Test20121011.zip
'Development note > C#' 카테고리의 다른 글
[C#] 파일 다운로드 예제 - 서버 폼 초기화, 이벤트 (0) | 2013.02.26 |
---|---|
[C#] 파일 다운로드 예제 - 소켓 부품 만들기 (0) | 2013.02.25 |
[C#] 파일 다운로드 예제- 화면 설계 (2) | 2013.02.24 |
[C#] AxWebBrowser 로 자동 로그인 소스 (웹 스크래핑) (9) | 2012.10.23 |
[C#] 확장형 브라우져 컨트롤 AxWebBrowser Extended Browser control(확장형 webbrowser) (5) | 2012.10.22 |
[C#] 스니퍼 (2) | 2012.10.09 |
[C#] 비프음 (0) | 2012.10.06 |
[C#] GDI Point 위치 (0) | 2012.10.01 |