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
标签:HTTP,socket,C#,22%,Send,message,GetBytes From: https://www.cnblogs.com/dxqNet/p/18019374