안녕하세요. 명월입니다.
이번 포스팅에서는 C#으로 웹 서버를 개발하는 것에 대해 알아보도록 하겠습니다. 웹 서버는 이미 아파치와 IIS 등등 좋은 웹서버는 많이 있습니다. 그래서 따로 이렇게 개발 안해도 무료로 좋은 웹서버가 많습니다. 그래도 웹 서버를 연습으로 만들어 보면 웹서버가 어떻게 이루어 지는 지 알 수 있고, 웹 서버가 아니더라도 다른 서버 프로그램을 개발할 때 응용이 가능합니다.
웹 서버를 만들기 전에 웹 프로토콜을 알아야 하는데 예전에 소개한 포스팅이 있습니다.
바로가기 - 프로토콜이란
먼저 아파치 서버를 이용해서 웹 서버에 접속하는 테스트 클라이언트 프로그램을 만들겠습니다.
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
여기 까지 됐으면 반대로 서버를 만들어 보도록 하겠습니다.
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 |