C# 通过socket 实现HTTP

http是最常用的互联网协议。http协议是基于tcp协议的,今天我打算使用C#语言,基于tcp编程自己实现http。适用于linux及mac系统。windows的tcp编程我没使用,但原理都是一样的。如果对网络编程不熟悉的,可以先熟悉一下网络编程。通过此例子,一定会对http协议的理解更上一层楼。

首先得有一个socket套接字,并且绑定到需要使用的端口上进行监听。

var socket= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
          
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1018);
socket.Bind(localEndPoint);//绑定
socket.Listen(1000);  //开始监听  

 

然后我们就可以接收客户端的请求了。我采用了死循环。

   while (true)
   {
       // 监听端口
       ProcessAccept(socket.Accept());
   }


// 监听的具体方法
private
static void ProcessAccept(Socket s) { try { byte[] data = new byte[1024]; var len = s.Receive(data); string request = Encoding.Default.GetString(data, 0, len); if (!string.IsNullOrWhiteSpace(request)) { if (request.Contains("GET / HTTP/1.1")) { int pageLen = 0; // 返回响应结果 s.Send(GetBytes("HTTP/1.1 200 OK\r\n")); //返回首部 s.Send(GetBytes("Content-Type: text/html\r\n")); s.Send(GetBytes("Connection: Keep-Alive\r\n")); s.Send(GetBytes($"Content-Length: {htmlPage.Length}\r\n")); // 发送换行符 表示结束 s.Send(GetBytes("\r\n")); s.Send(GetBytes(htmlPage)); } else if (request.Contains("/on")) { // 返回响应结果 s.Send(GetBytes("HTTP/1.1 200 OK\r\n")); //返回首部 s.Send(GetBytes("Content-Type: application/octet-stream\r\n")); s.Send(GetBytes("Connection: Keep-Alive\r\n")); s.Send(GetBytes($"Content-Length: {"On".Length}\r\n")); // 发送换行符 表示结束 s.Send(GetBytes("\r\n")); s.Send(GetBytes("On")); } else { s.Send(System.Text.Encoding.UTF8.GetBytes("ERROR Request")); } } } catch (SocketException ex) { //TODO 异常处理 } s.Close(); }

 

就是不停的调用accept去接受客户端的连接,accept会阻塞函数的执行,当有tcp客户端连接到来的时候它才会返回。accept函数的返回值是一个新的socket套接字。这个套接字是专门用来和该连接的客户端交互的。每个客户端都会有一个专门的套接字。


http请求数据包括请求行,消息头,消息正文三部分,而响应数据同样包括响应行,响应头,响应正文三部分。主要需要的是换行需要用\r\n表示还有就是有和正文之间有一个空行。
 
这里贴一下我测试时浏览器发来的请求数据
GET / HTTP/1.1\r\n
Host: 127.0.0.1\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
sec-ch-ua: \"Google Chrome\";v=\"105\", \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"105\"\r\n
sec-ch-ua-mobile: ?0\r\n
sec-ch-ua-platform: \"macOS\"\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n
Sec-Fetch-Site: none\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Sec-Fetch-Dest: document\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22182d98f2ee11c1-032ff8224617bd2-1b525635-1296000-182d98f2ee2192d%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22url%E7%9A%84domain%E8%A7%A3%E6%9E%90%E5%A4%B1%E8%B4%A5%22%2C%22%24latest_search_keyword%22%3A%22url%E7%9A%84domain%E8%A7%A3%E6%9E%9

我给客户端回复的响应数据如下

    string message ="";
    message+="HTTP/1.1 200 OK\r\n";                                    //响应行
    message+="Content-Type:text/html\r\n";                             //响应头
    message+="server:Tengine \r\n";                                    //响应头
    message+="name:LiaoKun \r\n";                                      //响应头
    message+="\r\n";                                                   //空行
    message+="<html><head>Hello,World!</head></html>\r\n";             //正文

 

效果如下:

 

完整代码:  https://gitee.com/dxqInterNet/socket_-http.git

 

posted @ 2024-02-18 15:22  BK小鬼  阅读(207)  评论(0编辑  收藏  举报