본문 바로가기

C#/근웹 연대기

c#으로 근본 없는 웹서버 개발기 1 : 소켓통신

⚠WARNING
ASP.NET에 대한 포스팅이 아닙니다
나가실 문은 오른쪽 하단입니다

 

 

asp, jsp, php, node.js, flask 등, 합해서 꽤 많은 시간을 그들과 보냈지만 무었하나 제대로 알 수가 없다.

그것들은 작업을 너무 쉽게 해주므로 크리티컬 한 오류가 나면 해결하기가 너무힘들고 의존증이 생겨 사람을 멍청하게 만든다. 너무쉽게 다가오는 것은 중독되기도 쉽다. 

최신 기술이라고 가져와 사용했는데, 자꾸 알 수 없는 이유로 서버가 뒤는지는 경우가 생겼던적이 있었다.

나는 그 날 본 오류가 아직 해결되었는지도 알 수 없는 상태로

그 떄의 웹프레임워크라는 것에 환멸을 느끼며  노브랜드워크로 웹을 끄적여볼까 한다.

가이드라인이 없으니 엄청난 삽질이 될거 같다.

그러나 어렵고 힘에 부치더라도 좁은 문으로 들어가자. 멸망으로 이끄는 문은 넓고 길도 널찍하여 그리로 들어가는 자들이 많다. 

 

소켓으로 소통하기

윈도우에는 윈속이라는 녀석이 있다. 자바의 달빅머신에도 비슷한 것이 있다. 또 리눅스에도 있을 것 이다. 🍎은 그 흔한 로고 한번 만저 본적이 없으므로 앞으로도 알랑가 모르겄다.

그러한 이유로 플랫폼이 달라지면 다시 코딩해야 하는 수고스러움이 생길것이다.

어쩐지 다행인지 .net 이 요즘에는 리눅스에서도 활동 할 수 있다고 한다. (잘한닷넷!)

이것이 윈속이다. 윈도 1등 공신 이지만 아이콘은 초라하다.

어느새 길어진 방문기록을 되집으며 소켓에 대한 글들을 찾아 해맸다.

아래의 소스는 클라이언트에서(브라우져) 리퀘스트를 주면 약 300B로 응답하는 서버이다.

System.Globalization.CultureInfo culInfo = new System.Globalization.CultureInfo("en-US");
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 80);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var sendData = @"<html><head>
                    <link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgo='>
                    </head><body>hello world</body></html>";
server.Bind(ipep);
server.Listen(100);

while (true)
{
    StringBuilder sb = new StringBuilder(100);
    Socket client = server.Accept();
    try
    {
        sb.AppendLine("HTTP/1.1 200 ok");
        sb.AppendLine("date: " + DateTime.UtcNow.ToString("ddd, dd MMM yyy HH':'mm':'ss 'GMT'", culInfo));
        sb.AppendLine("server: test server");
        sb.AppendLine("Content-Length: " + sendData.Length);
        sb.AppendLine("content-type:text/html; charset=UTF-8");
        sb.AppendLine();
        sb.AppendLine(sendData);
        var bytes = Encoding.UTF8.GetBytes(sb.ToString());
        client.Send(bytes);
        Thread.Sleep(10);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
    finally
    {
        client.Close();
    }
}

응답해더의 내용을 작성하고 hello world를 보내주는 간단한 내용이다. 헤더가 없으면 작동은 하지만 오류가 생길 수 있으므로 기본 구색은 갖추어야 할 필요가 있다.

첫줄은 영문식 날짜를 표기 하려면 필요하다. (국내 사이트도 영문식 표기를 사용하는듯)
저것을 안쓰고 그냥  출력 하면 한글이 깨져서 보인다.
컨텐츠 길이는 대충적으면 오류를 밷는다. (처음부터 없으면 오류도 없다.)
그리고 send후에 sleep을 안시켜주면 전송하다 끊어 버리는지 페이지가 뻑 날 떄 가 있다. (초반부터 깝깝하다)
html에 link rel 아이콘은 없으면 브라우저로부터 자꾸 리퀘스트가 오므로 넣어주는것이 트래픽을 줄 일 수 있다.

초반에 왜 자꾸 두번씩 요청하는지 헤메였다.
그렇다. 프레임워크를 쓰면 잘 모를 수 있는 일인것이다.

sb.AppendLine();  //이것은 뺴면 오류가 난다, 헤더와 바디의 경계선인듯 하다.

헤더에 관한 자세한 정보는 아래의 모질라문서를 참고하자

 

HTTP 메시지 - HTTP | MDN

HTTP 메시지는 서버와 클라이언트 간에 데이터가 교환되는 방식입니다. 메시지 타입은 두 가지가 있습니다. 요청(request)은 클라이언트가 서버로 전달해서 서버의 액션이 일어나게끔 하는 메시지

developer.mozilla.org

つづく