1. 程式人生 > >Socket程式設計-傳送HTTP請求

Socket程式設計-傳送HTTP請求

從TCP/IP模型的邏輯層面上來看,.Net類可以視為包含3個主要層次:請求/響應層、應用協議層以及傳輸層。WebRequest和WebResponse工作在請求/響應層,支援HTTP、TCP和UDP的類組成了應用協議層,而Socket類處於傳輸層。傳輸層位於這個結構的最底層,當其上層的應用協議層和請求/響應層不能滿足應用程式的特殊需要時,就需要使用傳輸層進行Socket程式設計。

Socket類包含在System.Net.Scokets名稱空間中,而一個Socket例項包含了一個端點的套接字資訊。

建構函式:public Socket(AddressFamily s, SocketType s, ProtocolType p)

其中,引數a指定Socket使用的定址方案,其值為AddressFamily.InterNetwork,表示使用IPv4的地址方案;s指定Socket的型別,其值為SocketType.Stream時,表示連線是基於流套接字的,而為SocketType.Dgram時,表示連線是基於資料報套接字的;p指定Socket使用的協議,其值為ProtocolType.Tcp時,表示連線協議是TCP協議,而為ProtocolType.Udp時,表明連線協議是UDP協議。

設計一個簡單的程式,根據指定URI,用套接字傳送HTTP請求,並將返回的資訊顯示在RichTextBox之中。

執行結果

原始碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace Socket_Request
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private string DoSocketGet(string request, IPAddress address)
        {
            string result = null;
            Encoding utf8 = Encoding.UTF8;                                      //指定編碼集
            Byte[] messages = utf8.GetBytes(request);
            Byte[] receives = new Byte[1024];                                   //用於快取接收到的資料

            try
            {
                int port = 80;                                                  //指定埠號              
                //建立套接字物件
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint endPoint = new IPEndPoint(address, port);            //建立端點

                s.Connect(endPoint);                                            //從本地連線遠端端點
                if (!s.Connected)
                {
                    result = "無法連線遠端伺服器";
                }
                s.Send(messages, messages.Length, 0);                           //傳送HTTP請求
                Int32 bytes = s.Receive(receives, receives.Length, 0);          //接受HTTP響應
                //將HTTP響應的位元組流裝換為字串
                result = utf8.GetString(receives, 0, bytes);                    
            }
            catch (SocketException ex)
            {
                MessageBox.Show("Source: " + ex.Source + "\nMessage:" + ex.Message,
                    "套接字錯誤", MessageBoxButtons.OK);
            }
           
            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string server = textUri.Text;
            string request = "GET / HTTP/1.1\r\nHost: " + server + "\r\nConnection:Close\r\n\r\n";
            //解析域名,得到IP地址
            IPHostEntry hostInfo = Dns.GetHostEntry(server);

            IPAddress address = null;
            if (hostInfo.AddressList.Length > 0)
            {
                address = hostInfo.AddressList[0];
            }

            textShow.Text = DoSocketGet(request, address);
        }
    }
}