- 浏览: 18081 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
zhenweiwei:
运行的时候报空指针??Collection entries = ...
JAVA调用svnkit获取svn树节点
因为项目需要,对C#进行了一些了解应用,现将收集资料存档,以备查。
C#用Socket读取网页,可实现加载头信息的用户认证
public class GetPageWithSocket { /// <summary> /// 使用socket得到网页html /// </summary> /// <param name="strUrl">网页url</param> /// <returns>网页html代码</returns> public string GetHtml(string strUrl,string username,string password) { bool hasRelocated = false; string strHost = GetHost(strUrl); int port = 80; if(strHost.IndexOf(":")!=-1) { port = int.Parse(strHost.Substring(strHost.IndexOf(":")+1)); strHost = strHost.Substring(0, strHost.IndexOf(":")); } string strGetHeader = ""; strGetHeader += "GET " + GetRelativeUrl(strUrl) + " HTTP/1.1\n"; strGetHeader += "Host: " + strHost + "\n"; string test = Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)); strGetHeader += "Authorization: Basic " + test + "\n"; strGetHeader += "Connection: Close\n"; strGetHeader += "\n"; byte[] getBytes = Encoding.ASCII.GetBytes(strGetHeader); try { int iTotalCount; byte[] responseBytes = GetHtmlOriginByte(strHost,port, getBytes, out iTotalCount); //得到网页 string strResponse = Encoding.UTF8.GetString(responseBytes, 0, iTotalCount); hasRelocated = HasRelocated(ref strResponse,username,password); if (!hasRelocated) //如果没跳转则转化字符后返回 { int iStart = FindBodyStartPosition(responseBytes); //总长度不再计算头http头部了 iTotalCount -= iStart; int iIndex = strResponse.IndexOf("\n\n"); if (iIndex != -1) { string strHeader = strResponse.Substring(0, iIndex);//头部 DecompressWebPage(ref responseBytes, ref iTotalCount, strHeader, iStart); //转码 strResponse = DecodeWebStringByHttpHeader(responseBytes, iTotalCount, strHeader); strResponse = DecodeWebStringByHtmlPageInfo(responseBytes, iTotalCount, strResponse); } } return strResponse; } catch (System.Exception ex) { return "error:get html error"; } } /// <summary> /// 得到网页原始字节数组 /// </summary> /// <param name="strHost">主机头</param> /// <param name="getBytes">Get字符串的字节数组形式</param> /// <param name="iTotalCount">接受的字节数</param> /// <returns>原始网页字节数组</returns> private byte[] GetHtmlOriginByte(string strHost,int port, byte[] getBytes, out int iTotalCount) { int iReponseByteSize = 400 * 1024; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Connect(strHost, port); socket.Send(getBytes); byte[] buffer = new byte[256]; byte[] responseBytes = new byte[iReponseByteSize]; int iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None); iTotalCount = iNumber; buffer.CopyTo(responseBytes, 0); while (iNumber > 0) { iNumber = socket.Receive(buffer, buffer.Length, SocketFlags.None); if (iTotalCount + iNumber >= responseBytes.Length) { //重新生成个更大的数组 byte[] temp = new byte[responseBytes.Length * 2]; //原数据copy到新数组中 responseBytes.CopyTo(temp, 0); buffer.CopyTo(temp, iTotalCount - 1); responseBytes = temp; //引用变更 } else { buffer.CopyTo(responseBytes, iTotalCount - 1); } iTotalCount += iNumber; //索引位置增加 } return responseBytes; } /// <summary> /// 解压网页 /// </summary> /// <param name="responseBytes">网页字节数组含http头</param> /// <param name="iTotalCount">数组长度</param> /// <param name="strHeader">Http头字符串</param> /// <param name="iStart">网页正文开始位置</param> private void DecompressWebPage(ref byte[] responseBytes, ref int iTotalCount, string strHeader, int iStart) { byte[] szSwapBuffer = new byte[iTotalCount]; Array.Copy(responseBytes, iStart, szSwapBuffer, 0, iTotalCount); Regex regZip = new Regex(@"Content-Encoding:\s+gzip[^\n]*\r\n", RegexOptions.IgnoreCase); if (regZip.IsMatch(strHeader)) { responseBytes = Decompress(szSwapBuffer); iTotalCount = responseBytes.Length; //解压后长度变了 } else { responseBytes = szSwapBuffer; } } /// <summary> /// 根据网页meta标记里面的字符编码解析字符串 /// </summary> /// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param> /// <param name="iTotalCount">网页内容字节数组长度</param> /// <param name="strResponse">网页内容字符串, 可能已经根据其它转码要求转换过的字符串</param> /// <returns>转好的字符串</returns> private string DecodeWebStringByHtmlPageInfo(byte[] responseBytes, int iTotalCount, string strResponse) { Regex regGB2312 = new Regex(@"<meta[^>]+Content-Type[^>]+gb2312[^>]*>", RegexOptions.IgnoreCase); Regex regGBK = new Regex(@"<meta[^>]+Content-Type[^>]+gbk[^>]*>", RegexOptions.IgnoreCase); Regex regBig5 = new Regex(@"<meta[^>]+Content-Type[^>]+Big5[^>]*>", RegexOptions.IgnoreCase); if (regGB2312.IsMatch(strResponse) || regGBK.IsMatch(strResponse)) strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes, 0, iTotalCount); if (regBig5.IsMatch(strResponse)) strResponse = Encoding.GetEncoding("Big5").GetString(responseBytes, 0, iTotalCount); return strResponse; } /// <summary> /// 根据Http头标记里面的字符编码解析字符串 /// </summary> /// <param name="responseBytes">网页内容字节数组(除http头以外的内容)</param> /// <param name="iTotalCount">网页内容字节数组长度</param> /// <param name="strHeader">http头的字符串</param> /// <returns>转好的字符串</returns> private string DecodeWebStringByHttpHeader(byte[] responseBytes, int iTotalCount, string strHeader) { string strResponse = ""; if (strHeader.Contains("charset=GBK") || strHeader.Contains("charset=gb2312")) { strResponse = Encoding.GetEncoding("GBK").GetString(responseBytes, 0, iTotalCount); } else strResponse = Encoding.UTF8.GetString(responseBytes, 0, iTotalCount); return strResponse; } /// <summary> /// 是否已跳转 /// </summary> /// <param name="strResponse">http响应字符串</param> /// <returns>bool值 是否跳转</returns> private bool HasRelocated(ref string strResponse,string username,string password) { bool hasRelocated = false; int iIndex = strResponse.IndexOf("\n\n"); if (iIndex != -1) { string strHeader = strResponse.Substring(0, iIndex);//头部 if (strResponse.StartsWith("HTTP/1.1 302") || strResponse.StartsWith("HTTP/1.1 301"))//跳转 { int iStart = strHeader.IndexOf("\nLocation: "); string strRelocateUrl = strHeader.Substring(iStart + "\nLocation: ".Length); int iEnd = strRelocateUrl.IndexOf("\n"); strRelocateUrl = strRelocateUrl.Substring(0, iEnd); strResponse = GetHtml(strRelocateUrl,username, password); //递归的获取 hasRelocated = true; } } return hasRelocated; } /// <summary> /// 查找html开始部分(去除了html头)\r\n\r\n后面第一个byte的位置 /// </summary> /// <param name="szHtmlBuffer">接受到的byte数组</param> /// <returns>第一个byte位置</returns> private int FindBodyStartPosition(byte[] szHtmlBuffer) { for (int i = 0; i < szHtmlBuffer.Length - 3; ++i) { if (szHtmlBuffer[i] == 13 && szHtmlBuffer[i + 1] == 10 && szHtmlBuffer[i + 2] == 13 && szHtmlBuffer[i + 3] == 10) return i + 4; } return -1; } /// <summary> /// 得到请求资源的相对路径 /// </summary> /// <param name="strUrl">Url字符串</param> /// <returns>url的相对路径</returns> private string GetRelativeUrl(string strUrl) { int iIndex = strUrl.IndexOf(@"//"); if (iIndex <= 0) return "/"; string strTemp = strUrl.Substring(iIndex + 2); iIndex = strTemp.IndexOf(@"/"); if (iIndex > 0) return strTemp.Substring(iIndex); else return "/"; } /// <summary> /// 根据Url得到host /// </summary> /// <param name="strUrl">url字符串</param> /// <returns>host字符串</returns> private string GetHost(string strUrl) { int iIndex = strUrl.IndexOf(@"//"); if (iIndex <= 0) return ""; string strTemp = strUrl.Substring(iIndex + 2); iIndex = strTemp.IndexOf(@"/"); if (iIndex > 0) return strTemp.Substring(0, iIndex); else return strTemp; } /// <summary> /// 解压gzip网页 /// </summary> /// <param name="szSource">压缩过的字符串字节数组</param> /// <returns>解压后的字节数组</returns> private byte[] Decompress(byte[] szSource) { MemoryStream msSource = new MemoryStream(szSource); //DeflateStream 也可以这儿 GZipStream stream = new GZipStream(msSource, CompressionMode.Decompress); byte[] szTotal = new byte[40 * 1024]; long lTotal = 0; byte[] buffer = new byte[8]; int iCount = 0; do { iCount = stream.Read(buffer, 0, 8); if (szTotal.Length <= lTotal + iCount) //放大数组 { byte[] temp = new byte[szTotal.Length * 10]; szTotal.CopyTo(temp, 0); szTotal = temp; } buffer.CopyTo(szTotal, lTotal); lTotal += iCount; } while (iCount != 0); byte[] szDest = new byte[lTotal]; Array.Copy(szTotal, 0, szDest, 0, lTotal); return szDest; } }
代码为转载,转载位置未存,望原作者见谅。
相关推荐
本教程将深入探讨如何使用C#编程语言以及SuperSocket库来构建一个高效、稳定的服务器端和客户端通信模型。SuperSocket是一个轻量级且易于使用的.NET Socket服务端开发框架,它为开发者提供了构建自定义网络应用的...
本示例中,我们将探讨如何使用C#的Socket类来实现发送和接收图片的功能。 首先,我们创建一个服务器端,其主要任务是监听客户端的连接请求,并将图片文件发送给客户端。在`Main`方法中,我们执行以下步骤: 1. **...
在Linux平台上,通过Socket进行PLC(可编程逻辑控制器)数据的读取是工业自动化领域常见的通信方式之一。本文将详细讲解如何利用Socket接口和Modbus TCP协议来实现这一功能。 首先,我们要理解什么是Socket。Socket...
c#与PLC通过SocketTcp通讯代码.仅通讯部分,不包含协议解析
本示例主要探讨如何使用C#的Socket类进行文件的传输,包括文件名和文件内容的同步发送与接收。这里我们将详细讲解实现这一功能的关键步骤和相关知识点。 首先,了解Socket的工作原理。Socket是TCP/IP协议栈的一部分...
在本文中,我们将深入探讨如何使用C#编程语言和Socket技术来实现一个基本的HTTP Web服务器。C#是一种面向对象的、类型安全的编程语言,广泛应用于Windows平台上的应用程序开发,包括网络服务。Socket是网络通信的...
对于标题中的“C# Socket编程 客户异步读取”,我们关注的是如何在客户端使用异步方法来读取服务器发送的数据。C#的异步编程模型主要基于.NET Framework的`async/await`关键字。在Socket编程中,我们可以使用`...
本文将深入探讨如何使用C#语言来实现Socket编程,特别是在处理异步通信和解决TCP粘包问题的第三阶段。C#提供了丰富的类库支持网络编程,使得开发者能够方便地构建基于TCP/IP的客户端和服务器应用。 首先,让我们...
C#中实现Modbus TCP通信,我们需要使用Socket类,它是.NET Framework提供的基础网络通信组件。Socket类提供了低级别的网络编程接口,可以用于创建TCP/IP或UDP/IP连接。在本例中,我们将专注于TCP,因为Modbus TCP是...
3. **读取文件**:使用FileStream或其它文件读取方式读取待发送的文件内容。 4. **数据分块**:大文件传输时,不能一次性将整个文件内容发送,而是需要将其分割成多个小块。 5. **发送数据**:使用Socket的Send...
在IT行业中,网络通信是不可或缺的一部分,而C#语言提供了强大的Socket类库,使得开发者能够构建高效、可靠的网络应用程序。本篇文章将深入探讨C#中的Socket异步传输,以及如何利用它进行网络通信。 首先,Socket是...
在本文中,我们将深入探讨如何使用C# Socket类进行文件传输,包括文件的发送和接收,以及在此过程中可能遇到的关键技术和注意事项。 1. **Socket基本概念** - Socket是基于TCP/IP协议族的通信接口,它允许应用程序...
标题中的“c#基于socket 服务器端TCP程序”指的是使用C#语言编写的一套服务器应用程序,它利用了Socket类库来处理TCP(传输控制协议)连接。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,广泛用于...
本示例主要探讨如何使用C#的Socket类进行文件的传输,具体是从客户端向服务器端发送文件。这个过程涉及到了网络编程的基本原理、Socket通信机制以及文件I/O操作。 首先,Socket是TCP/IP协议族的基础,它为应用程序...
在C#中,如果使用Socket进行TCP通信,就需要处理这种现象,以确保正确地解析接收到的数据。 "TCP\Socket粘包处理(加长度头)"这个主题主要涉及如何解决这个问题。在TCP中处理粘包的关键是添加一种机制来区分不同的...
在C#中,我们可以先将文件读取为字节数组,然后通过Socket的Send方法分块发送。服务器端接收到数据后,再写入到本地文件系统,恢复成原始文件。这个过程中,需要注意文件的分块发送和接收,以及正确处理文件头信息,...
总结来说,"Socket异步发送读取,客户端和服务端"这个主题涵盖了C#中使用Socket进行网络通信的核心技术,包括异步发送和接收数据,以及与Winform界面的交互。理解并掌握这些知识点对于开发网络应用至关重要。
例如,`RWFile.cs`可能包含用于读取和写入文件的函数,可能使用`FileStream`打开文件,然后使用`StreamReader`或`StreamWriter`进行读写操作。 4. **日志记录(LogHelper.cs)** `LogHelper.cs`文件可能包含了日志...
在IT领域,网络通信是不可或缺的一部分,而C#作为.NET框架的主要编程语言,提供了丰富的库来支持网络编程,其中就包括Socket。本篇文章将详细解析标题中的"C#中Socket服务端通讯的代码",以及如何实现高效、稳定的...