我自己用Socket写了一个HttpClient ,感觉性能不太好,在网上找了一些
发现都无法设置IP
下面是我自己实现的HttpClient
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace PageCache.Common
{
public class HttpDataInfo
{
public HttpDataInfo()
{
headers = new NameValueCollection();
}
public int StatusCode { get; set; }
public string StatusDescription { get; set; }
public string Scheme { get; set; }
NameValueCollection headers;
public NameValueCollection Headers
{
get { return headers; }
set { headers = value; }
}
public string HeadersStrings { get; set; }
public int ContentLength { get; set; }
}
public class HttpData : HttpDataInfo
{
public byte[] BodyData { get; set; }
}
public class HttpClient
{
const string Sign_Content_Length = "Content-Length";
const string Sign_Header_End = "\r\n";
const string Sign_Chunked_End = "\r\n";
const string Sign_Chunked = "chunked";
const int None_Data = -1;
const int Buffer_Size = 256;
byte[] ParseChunkedData(List<byte> data)
{
int endPosition = data.Count;
List<byte> list = new List<byte>();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Count; i++)
{
byte b = data[i];
char c = (char)b;
sb.Append(c);
string line = sb.ToString();
int inx = line.IndexOf(Sign_Chunked_End);
if (inx > 0)
{
string hex = line.Substring(0, inx);
int count = Convert.ToInt32(hex, 16);
if (count > 0)
{
var range = data.GetRange(i + 1, count);
list.AddRange(range);
i = i + count + 2;
}
else if (count == 0)
{
break;
}
sb.Clear();
}
}
return list.ToArray();
}
bool IsSame(char[] chars, List<byte> bytes)
{
if (chars.Length != bytes.Count)
{
return false;
}
bool same = true;
for (int i = 0; i < chars.Length; i++)
{
same = same && chars[i] == bytes[i];
}
return same;
}
char[] Sign_End = { '\r', '\n', '\r', '\n' };
int receiveTimeout = 5000;
/// <summary>
/// 接收超时默认2秒
/// </summary>
public int ReceiveTimeout
{
get { return receiveTimeout; }
set { receiveTimeout = value; }
}
int sendTimeout = 5000;
/// <summary>
/// 发送超时默认1秒
/// </summary>
public int SendTimeout
{
get { return sendTimeout; }
set { sendTimeout = value; }
}
public Log ErrorLog { get; set; }
List<byte> ReceiveAllData(Socket socket, byte[] headersData)
{
int zero_times = 0;
int zero_max = 3;
List<byte> list = new List<byte>(1024 * 64);
int nowContentLength = 0;
byte[] buffer = new byte[Buffer_Size];
try
{
while (true)
{
int receiveCount = socket.Receive(buffer, Buffer_Size, SocketFlags.None);
if (receiveCount > 0)
{
zero_times = 0;
for (int i = 0; i < receiveCount; i++)
{
list.Add(buffer[i]);
}
nowContentLength += receiveCount;
}
if (receiveCount == 0 || receiveCount < Buffer_Size)
{
zero_times++;
if (zero_times >= zero_max)
{
break;
}
}
}
}
catch (Exception ex)
{
if (ErrorLog != null)
{
ErrorLog.Write(ex.ToString());
ErrorLog.Write(Encoding.UTF8.GetString(headersData));
}
}
return list;
}
public HttpData GetData(Socket socket, byte[] headersData)
{
List<byte> list_data = ReceiveAllData(socket, headersData);
byte[] header_data = null;
List<byte> body_data_list = null;
int sign_len = Sign_End.Length;
//拆分出 HTTP Header Body
if (list_data.Count > sign_len)
{
for (int i = 0; i <= list_data.Count - sign_len; i++)
{
var range = list_data.GetRange(i, sign_len);
if (IsSame(Sign_End, range))
{
header_data = list_data.GetRange(0, i + sign_len).ToArray();
if (header_data.Length < list_data.Count)
{
body_data_list = list_data.GetRange(i + sign_len, list_data.Count - header_data.Length);
}
break;
}
}
}
if (header_data == null)
{
return null;
}
string headerString = Encoding.ASCII.GetString(header_data);
HttpDataInfo info = ParseHeaderString(headerString);
HttpData data = null;
if (info != null)
{
data = new HttpData
{
HeadersStrings = info.HeadersStrings
,
Scheme = info.Scheme
,
StatusCode = info.StatusCode
,
StatusDescription = info.StatusDescription
,
Headers = info.Headers
};
data.BodyData = new byte[0];
if (body_data_list != null)
{
if (info.ContentLength > 0)
{
if (body_data_list == null)
{
throw new Exception("ContentLength>0 and ReceiveBodyData is null");
}
else
{
data.BodyData = body_data_list.ToArray();
}
}
else if (info.ContentLength == None_Data)
{
string tran = info.Headers["Transfer-Encoding"] ?? string.Empty;
if (tran.Equals(Sign_Chunked, StringComparison.OrdinalIgnoreCase))
{
if (body_data_list == null)
{
throw new Exception("Transfer-Encoding is " + Sign_Chunked + " and ReceiveBodyData is null");
}
else
{
data.BodyData = ParseChunkedData(body_data_list);
}
}
else
{
data.BodyData = body_data_list.ToArray();
}
}
}
if (data.BodyData != null)
{
data.ContentLength = data.BodyData.Length;
}
else
{
data.ContentLength = 0;
}
}
return data;
}
public HttpData GetData(string host, byte[] headersData)
{
return GetData(host, 80, headersData);
}
public HttpData GetData(string host, string headersString)
{
return GetData(host, Encoding.ASCII.GetBytes(headersString));
}
public HttpData GetData(string host, int port, string headersString)
{
return GetData(host, port, Encoding.ASCII.GetBytes(headersString));
}
public HttpData GetData(string host, int port, byte[] headersData)
{
HttpData data = null;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.ReceiveTimeout = receiveTimeout;
socket.SendTimeout = sendTimeout;
int loopTimes = 0;
int loopTimesMax = 2;
loop:
if (!socket.Connected)
{
socket.Connect(host, port);
}
if (!socket.Connected)
{
loopTimes++;
if (loopTimes < loopTimesMax)
{
goto loop;
}
}
if (socket.Connected)
{
socket.Send(headersData);
data = GetData(socket, headersData);
socket.Shutdown(SocketShutdown.Both);
}
}
return data;
}
public HttpData GetData(IPEndPoint address, string headersString)
{
return GetData(address, Encoding.ASCII.GetBytes(headersString));
}
public HttpData GetData(IPEndPoint address, byte[] headersData)
{
HttpData data = null;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.ReceiveTimeout = receiveTimeout;
socket.SendTimeout = sendTimeout;
int loopTimes = 0;
int loopTimesMax = 2;
loop:
if (!socket.Connected)
{
socket.Connect(address);
}
if (!socket.Connected)
{
loopTimes++;
if (loopTimes < loopTimesMax)
{
goto loop;
}
}
if (socket.Connected)
{
socket.Send(headersData);
data = GetData(socket, headersData);
socket.Shutdown(SocketShutdown.Both);
}
}
return data;
}
public static HttpDataInfo ParseHeaderString(string headersStringText)
{
string[] headersStrings = headersStringText.Split(new string[] { Sign_Header_End }, StringSplitOptions.None);
if (headersStrings.Length > 0)
{
HttpDataInfo info = new HttpDataInfo();
info.ContentLength = None_Data;
info.HeadersStrings = headersStringText;
string firstLine = headersStrings[0].Trim();
if (!string.IsNullOrEmpty(firstLine))
{
int inx_space1 = firstLine.IndexOf(' ');
int inx_space2 = firstLine.IndexOf(' ', inx_space1 + 1);
if (inx_space2 > inx_space1 && inx_space1 > 0)
{
string codeString = firstLine.Substring(inx_space1 + 1, inx_space2 - inx_space1);
int code = 0;
if (int.TryParse(codeString, out code))
{
info.StatusCode = code;
}
info.Scheme = firstLine.Substring(0, inx_space1);
info.StatusDescription = firstLine.Substring(inx_space2 + 1);
}
}
string headerSplitSign = ": ";
if (headersStrings.Length > 1)
{
for (int i = 1; i < headersStrings.Length; i++)
{
string header = headersStrings[i].Trim();
int signIndex = header.IndexOf(headerSplitSign);
int valueIndex = signIndex + headerSplitSign.Length;
if (signIndex > 0 && valueIndex < header.Length)
{
string key = header.Substring(0, signIndex);
string value = header.Substring(valueIndex);
if (key.Equals(Sign_Content_Length, StringComparison.OrdinalIgnoreCase))
{
int contentLength = 0;
if (int.TryParse(value, out contentLength))
{
info.ContentLength = contentLength;
}
else
{
info.ContentLength = None_Data;
}
}
info.Headers[key] = value;
}
}
}
return info;
}
return null;
}
}
}
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx
看下这个 是你想要的吗