[C#] 웹서버 개발하기

개발 노트/C#  2012.10.15 18:27



안녕하세요. 명월입니다.

이번 포스팅에서는 C#으로 웹서버를 개발하는 것에 대해 알아보도록 하겠습니다. 웹서버는 이미 아파치 라던가 IIS 등등 좋은 웹서버는 많이 있습니다. 그래서 굳히 이런거 개발 안해도 무료로 좋은 웹서버가 많은데 라고 생각할 수 있는데 웹서버를 개발이 어떻게 이루어 지는 지 알아봄으로서 프로토콜이 어떤 형식으로 이루어지구나 라는 것을 알고 굳이 웹서버가 아니더라도 다른 서버 프로그램을 개발할 때 응용이 가능한 부분이니 확인 하는 차원으로 개발해 보도록하겠습니다.

 

프로토콜이 무엇인가에 대해서는 간략하게 소개를 한 포스팅이 있으니 확인 하시면 도움이 될 듯합니다.

바로가기 - 프로토콜이란

 

그럼 이렇게 앞서서 웹서버를 만들기에 앞서서 우리가 웹서버를 접속해 보도록 하겠습니다.

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Net;
  5 using System.Net.Sockets;
  6
  7 namespace blog_20121015
  8 {
  9     class Program
10     {
11         static void Main(string[] args)
12         {
13             new Program();
14             Console.ReadLine();
15         }
16         public Program() {
17             IPHostEntry host = Dns.Resolve("nowonbun.tistory.com");
18 IPAddress IP = host.AddressList[0];
19             Console.WriteLine(IP.ToString());
20             IPEndPoint ipep = new IPEndPoint(IP, 80);
21             Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
22             client.Connect(ipep);
23             String Send = @"
24 GET / HTTP/1.1\r\n
25 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
26 Accept-Language: ko\r\n
27 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
28 Accept-Encoding: gzip, deflate\r\n
29 Host: 127.0.0.1\r\n
30 Connection: Keep-Alive\r\n
31 "
;
32             client.Send(Encoding.Default.GetBytes(Send));
33             client.Send(Encoding.Default.GetBytes("\r\n"));
34             client.Send(Encoding.Default.GetBytes("\r\n"));
35             byte[] _data = new byte[4096];
36             client.Receive(_data);
37             client.Close();
38             Console.WriteLine(Encoding.Default.GetString(_data));
39         }
40     }
41 }
42

 

String Send 에 있는 부분에 HTTP 프로토콜 규약에 맞추어 Send를 보내는 부분 입니다.

  

 

 

위 결과 화면은 비록 400 Bad Request 라고 응답이 호출 되었지만 분명 tistory 에서는 프로토콜에 맞게 응신이 왔습니다. (Tistory 는 Apache 를 쓰는 군요. ㅎㅎㅎ)

 

여기까지 참고 소스 첨부하겠습니다.

첨부 파일 - blog_20121015.zip

 

여기 까지 됐으면 반대로 서버를 만들어 보도록 하겠습니다.

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Net;
  5 using System.Net.Sockets;
  6 using System.IO;
  7
  8 namespace Test20121011
  9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             new Program();
15         }
16         public Program() {
17             IPEndPoint ipep = new IPEndPoint(IPAddress.Any,9999);
18             Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
19             server.Bind(ipep);
20             server.Listen(20);
21             while (true){
22                 Socket client = server.Accept();
23                 try
24                 {
25                     String file = Recieve(client);
26                     FileInfo FI = new FileInfo(file);
27                     client.Send(Header(client, FI));
28                 }
29                 catch { }
30                 finally {
31                     client.Close();
32                 }
33             }
34         }
35         public String Recieve(Socket client) {
36             String _data_str = "";
37             byte[] _data = new byte[4096];
38             client.Receive(_data);
39             Console.WriteLine(Encoding.Default.GetString(_data).Trim('\0'));
40             String[] _buf = Encoding.Default.GetString(_data).Split("\r\n".ToCharArray());
41             if (_buf[0].IndexOf("GET") != -1)
42             {
43                 _data_str = _buf[0].Replace("GET ", "").Replace("HTTP/1.1", "").Trim();
44             }
45             else {
46                 _data_str = _buf[0].Replace("POST ", "").Replace("HTTP/1.1", "").Trim();
47             }
48             if (_data_str.Trim() == "/") {
49                 _data_str += "index.html";
50             }
51             int pos = _data_str.IndexOf("?");
52             if (pos > 0)
53             {
54                 _data_str = _data_str.Remove(pos);
55             }
56             return "web"+_data_str;
57         }
58         public byte[] Header(Socket client,FileInfo FI) {
59             byte[] _data2 = new byte[FI.Length];
60             try
61             {
62                 FileStream FS = new FileStream(FI.FullName, FileMode.Open, FileAccess.Read);
63                 FS.Read(_data2, 0, _data2.Length);
64                 FS.Close();
65
66                 String _buf = "HTTP/1.0 200 ok\r\n";
67                 _buf += "Data: " + FI.CreationTime.ToString() + "\r\n";
68                 _buf += "server: Myung server\r\n";
69                 _buf += "Content-Length: " + _data2.Length.ToString() + "\r\n";
70                 _buf += "content-type:text/html\r\n";
71                 _buf += "\r\n";
72                 client.Send(Encoding.Default.GetBytes(_buf));
73             }
74             catch {
75                 String _buf = "HTTP/1.0 100 BedRequest ok\r\n";
76                 _buf += "server: Myung server\r\n";
77                 _buf += "content-type:text/html\r\n";
78                 _buf += "\r\n";
79                 client.Send(Encoding.Default.GetBytes(_buf));
80                 _data2 = Encoding.Default.GetBytes("Bed Request");
81             }
82             return _data2;
83         }
84     }
85 }
86

 

 

 

 

위 소스에서 보면 요청이 오면 index.html 파일을 전송하는 것으로 만들었습니다.

그러면 index.html 를 만들어 보도록하겠습니다.

 

 

실제 웹서버처럼 이미지도 넣어보고 marquee 태그도 넣어보고 js도 넣어 보았습니다.

그럼 서버를 올려보도록 하겠습니다.

 

 

실제 서버처럼 작동을 합니다. 물론 서버스크립트를 붙히지 않아 html 밖에 되지는 않겠지만 이 정도면 기본적인 웹서버 기능은 작동 하겠습니다.

 

( 사실 프로토콜의 개념을 함께 설명하려고 했으나 너무 코드위주의 설명이 되어버렸습니다. 그러나 한번 따라서 코딩해보면 프로토콜 개념이 한번에 잡히니 한번 따라 코딩해 보시길 추천합니다.)

 

참조 파일 : Test20121011.zip


댓글 0개가 달렸습니다.
댓글쓰기