网络插座Socket

5 篇文章 0 订阅
2 篇文章 0 订阅

Unix提供了类似于文件操作的网络操作方式--Socket。通过Socket,程序员可以像操作文件一样通过打开、读取、写入、关闭等操作完成网络编程。

当Socket开发网络应用程序时,需要考虑使用的网络类型:

1、Socket类型,使用网络协议的类别,IPv4的类型为PF_INET

2、数据通信的类型,常见的数据报(SOCK_DGRAM)、数据流(SOCK_STREAM)

3、使用的网络协议,比如:TCP协议

下面演示几种使用Socket编程创建一个简单的Web服务器,该服务器通过端口号提供访问,向浏览器返回一个固定页面

1、通过Socket类实现:

private static void SocketDemo()
        {
            //取得本机换回地址
            IPAddress ip = IPAddress.Loopback;
            //端点=Ip+端口
            IPEndPoint endPoint = new IPEndPoint(ip, 8888);
            //参数分别为:使用网络协议的类别,数据通信的类型,使用的网络协议
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(endPoint);
            socket.Listen(10);
            Console.WriteLine("开始监听,端口号:{0}。", endPoint.Port);

            while (true)
            {
                //当接收到客户端请求时才继续往下执行
                Socket client = socket.Accept();
                //获取请求的端点
                Console.WriteLine(client.RemoteEndPoint);
                byte[] buffer = new byte[4096];
                //获取请求数据长度
                int len = client.Receive(buffer, 4096, SocketFlags.None);

                System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
                //将获取的内容编码为一个字符串
                string requestString = utf8.GetString(buffer, 0, len);

                Console.WriteLine(requestString);

                //消息格式:请求状态行+消息头+消息体  3部分
                string statusLine = "Http/1.1 200 OK\r\n";
                byte[] statusLineBytes = utf8.GetBytes(statusLine);
                //准备发送到客户端的网页
                string responseBody = "<html><head><title>From Socket Server</title></head><body><h1>Hello,Socket</h1></body></html>";
                byte[] responseBodyBytes = utf8.GetBytes(responseBody);
                string responseHeader = string.Format("Content-Type:Text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", responseBody.Length);
                byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);
                client.Send(statusLineBytes);
                client.Send(responseHeaderBytes);
                client.Send(new byte[] { 13, 10 });
                client.Send(responseBodyBytes);
                client.Close();
                if (Console.KeyAvailable)
                    break;



            }
            socket.Close();
        }
2、为了简化不再需要设置使用的网络协议等细节,.NET在System.Net.Socket命名空间中提供了TcpListener类:

//用TcpListener来替代Socket,就不用再设置网络协议等细节
        private static void TcpListenerDemo()
        {
            IPAddress ip = IPAddress.Loopback;
            IPEndPoint endpPoint = new IPEndPoint(ip,8888);
            //创建tcp监听器
            TcpListener newServer = new TcpListener(endpPoint);
            newServer.Start();
            Console.WriteLine("开始监听....");
            while (true)
            {
                //等待客户端连接
                TcpClient newClient = newServer.AcceptTcpClient();
                Console.WriteLine("已经建立连接!");
                //得到一个网络流
                NetworkStream ns = newClient.GetStream();

                byte[] request = new byte[4096];
                //获取请求数据长度

                System.Text.Encoding utf8 = System.Text.Encoding.UTF8;

                int len = ns.Read(request, 0, 4096);
                //将获取的内容编码为一个字符串
                string requestString = utf8.GetString(request, 0, len);

                Console.WriteLine(requestString);

                //消息格式:请求状态行+消息头+"换行"+消息体  3部分
                string statusLine = "Http/1.1 200 OK\r\n";
                byte[] statusLineBytes = utf8.GetBytes(statusLine);
                //准备发送到客户端的网页
                string responseBody = "<html><head><title>From Socket Server</title></head><body><h1>Hello,TcpListener</h1></body></html>";
                byte[] responseBodyBytes = utf8.GetBytes(responseBody);
                string responseHeader = string.Format("Content-Type:Text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", responseBody.Length);
                byte[] responseHeaderBytes = utf8.GetBytes(responseHeader);
                ns.Write(statusLineBytes, 0, statusLineBytes.Length);
                ns.Write(responseHeaderBytes, 0, responseHeaderBytes.Length);
                ns.Write(new byte[] { 13, 10 }, 0, 2);
                ns.Write(responseBodyBytes, 0, responseBodyBytes.Length);
                newClient.Close();
                if (Console.KeyAvailable)
                    break;
            }
            newServer.Stop();
        }

3、为了进一步简化HTTP协议的监听器,.Net在命名空间System.Net中提供了HttpListener类:

private static void HttpListenerDemo()
        {
            if (!HttpListener.IsSupported)
            {
                throw new System.InvalidOperationException("使用HttpListener 必须为Windows XP SP2 或 Server 2003 以上的系统");
            }

            string[] prefixes = new string[] { "http://localhost:8888/" };
            //创建监听器
            HttpListener listener = new HttpListener();
            //增加监听的前缀
            foreach (string s in prefixes)
            {
                listener.Prefixes.Add(s);
            }
            listener.Start();
            Console.WriteLine("开始监听....");
            while (true)
            {
                //阻塞线程,直到请求到达
                HttpListenerContext context = listener.GetContext();
                //获取请求对象
                HttpListenerRequest request = context.Request;
                //输出相关信息
                Console.WriteLine("{0} {1} Http/1.1",request.HttpMethod,request.RawUrl);
                Console.WriteLine("Accept:{0}",string.Join(",",request.AcceptTypes));
                Console.WriteLine("Accept-Languages:{0}", string.Join(",", request.UserLanguages));
                Console.WriteLine("User_Agent:{0}",request.UserAgent);
                Console.WriteLine("Accept-Encoding:{0}",request.Headers["Accept-Encoding"]);
                Console.WriteLine("Connection:{0}", request.KeepAlive ? "Keep-Alive" : "close");
                Console.WriteLine("Host:{0}",request.UserHostName);
                Console.WriteLine("Pragma:{0}",request.Headers["Pragma"]);

                //获取回应对象
                HttpListenerResponse response = context.Response;
                string responseString = @"<html><head><title>From Socket Server</title></head><body><h1>Hello,HttpListener</h1></body></html>";
                //设置回应头部内容,长度,编码
                response.ContentLength64 = System.Text.Encoding.UTF8.GetByteCount(responseString);
                response.ContentType = @"text/html;charset=UTF-8";
                //输出回应内容
                System.IO.Stream output = response.OutputStream;
                System.IO.StreamWriter writer = new System.IO.StreamWriter(output);
                writer.Write(responseString);
                //关闭输出流
                writer.Close();
                if (Console.KeyAvailable)
                    break;
            }
            //关闭服务器
            listener.Stop();
        }

以上三种方法都实现了服务器接收客户端的请求,并对其进行回应,回应的消息由服务器生成,在真正处理的时候,我们需要根据接收浏览器的请求信息,给出不同的处理及回应。


以上内容参考书籍:ASP.NET本质论(郝冠军 著)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯的世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值