从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);
}
}
}