HttpHelper类及调用
首先列出HttpHelper类
/// <summary>
/// Http操作类
/// </summary>
public class HttpHelper
{
private static log4net.ILog mLog = log4net.LogManager.GetLogger("HttpHelper"); [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData); [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool InternetGetCookie(string lpszUrlName, string lbszCookieName, StringBuilder lpszCookieData, ref int lpdwSize);
public static StreamReader mLastResponseStream = null;
public static System.IO.StreamReader LastResponseStream
{
get { return mLastResponseStream; }
}
private static CookieContainer mCookie = null;
public static CookieContainer Cookie
{
get { return mCookie; }
set { mCookie = value; }
}
private static CookieContainer mLastCookie = null;
public static HttpWebRequest CreateWebRequest(string url, HttpRequestType httpType, string contentType, string data, Encoding requestEncoding, int timeout, bool keepAlive)
{
if (String.IsNullOrWhiteSpace(url))
{
throw new Exception("URL为空");
}
HttpWebRequest webRequest = null;
Stream requestStream = null;
byte[] datas = null;
switch (httpType)
{
case HttpRequestType.GET:
case HttpRequestType.DELETE:
if (!String.IsNullOrWhiteSpace(data))
{
if (!url.Contains('?'))
{
url += "?" + data;
}
else url += "&" + data;
}
if(url.StartsWith("https:"))
{
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
}
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = Enum.GetName(typeof(HttpRequestType), httpType);
if (contentType != null)
{
webRequest.ContentType = contentType;
}
if (mCookie == null)
{
webRequest.CookieContainer = new CookieContainer();
}
else
{
webRequest.CookieContainer = mCookie;
}
if (keepAlive)
{
webRequest.KeepAlive = keepAlive;
webRequest.ReadWriteTimeout = timeout;
webRequest.Timeout = ;
mLog.Info("请求超时时间..." + timeout);
}
break;
default:
if (url.StartsWith("https:"))
{
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
}
webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = Enum.GetName(typeof(HttpRequestType), httpType);
if (contentType != null)
{
webRequest.ContentType = contentType;
}
if (mCookie == null)
{
webRequest.CookieContainer = new CookieContainer();
}
else
{
webRequest.CookieContainer = mCookie;
}
if (keepAlive)
{
webRequest.KeepAlive = keepAlive;
webRequest.ReadWriteTimeout = timeout;
webRequest.Timeout = ;
mLog.Info("请求超时时间..." + timeout);
}
if (!String.IsNullOrWhiteSpace(data))
{
datas = requestEncoding.GetBytes(data);
}
if (datas != null)
{
webRequest.ContentLength = datas.Length;
requestStream = webRequest.GetRequestStream();
requestStream.Write(datas, , datas.Length);
requestStream.Flush();
requestStream.Close();
}
break;
}
//mLog.InfoFormat("请求 Url:{0},HttpRequestType:{1},contentType:{2},data:{3}", url, Enum.GetName(typeof(HttpRequestType), httpType), contentType, data);
return webRequest;
}
public static CookieContainer GetLastCookie()
{
return mLastCookie;
}
/// <summary>
/// 设置HTTP的Cookie,以后发送和请求用此Cookie
/// </summary>
/// <param name="cookie">CookieContainer</param>
public static void SetHttpCookie(CookieContainer cookie)
{
mCookie = cookie;
}
private static HttpWebRequest mLastAsyncRequest = null;
public static HttpWebRequest LastAsyncRequest
{
get { return mLastAsyncRequest; }
set { mLastAsyncRequest = value; }
}
/// <summary>
/// 发送请求
/// </summary>
/// <param name="url">请求Url</param>
/// <param name="httpType">请求类型</param>
/// <param name="contentType">contentType:application/x-www-form-urlencoded</param>
/// <param name="data">请求数据</param>
/// <param name="encoding">请求数据传输时编码格式</param>
/// <returns>返回请求结果</returns>
public static string SendRequest(string url, HttpRequestType httpType, string contentType, string data, Encoding requestEncoding, Encoding reponseEncoding, params AsyncCallback[] callBack)
{ int timeout = ;
bool keepAlive = false;
if (callBack != null && callBack.Length > && callBack[] != null)
{
keepAlive = true;
timeout = **;
mLog.Info("写入读取超时时间..." + timeout);
}
// mLog.Info("开始创建请求....");
HttpWebRequest webRequest = CreateWebRequest(url, httpType, contentType, data, requestEncoding,timeout,keepAlive);
string ret = null;
// mLog.Info("创建请求结束....");
if (callBack != null && callBack.Length > && callBack[] != null)
{
// mLog.Info("开始异步请求....");
mLastAsyncRequest = webRequest;
webRequest.BeginGetResponse(callBack[], webRequest);
}
else
{
// mLog.Info("开始同步请求....");
StreamReader sr = new StreamReader(webRequest.GetResponse().GetResponseStream(), reponseEncoding);
ret = sr.ReadToEnd();
sr.Close();
}
mLastCookie = webRequest.CookieContainer;
//mLog.InfoFormat("结束请求 Url:{0},HttpRequestType:{1},contentType:{2},结果:{3}", url, Enum.GetName(typeof(HttpRequestType), httpType), contentType,ret);
return ret;
} /// <summary>
/// Http上传文件
/// </summary>
public static string HttpUploadFile(string url, string path)
{
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.AllowWriteStreamBuffering = false;
request.SendChunked = true;
request.Method = "POST";
request.Timeout = ; string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
int pos = path.LastIndexOf("\\");
string fileName = path.Substring(pos + ); //请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
request.ContentLength = itemBoundaryBytes.Length + postHeaderBytes.Length + fs.Length + endBoundaryBytes.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(itemBoundaryBytes, , itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, , postHeaderBytes.Length);
int bytesRead = ; int arrayLeng = fs.Length <= ? (int)fs.Length : ;
byte[] bArr = new byte[arrayLeng];
int counter = ;
while ((bytesRead = fs.Read(bArr, , arrayLeng)) != )
{
counter++;
postStream.Write(bArr, , bytesRead);
}
postStream.Write(endBoundaryBytes, , endBoundaryBytes.Length);
} //发送请求并获取相应回应数据
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//直到request.GetResponse()程序才开始向目标网页发送Post请求
using (Stream instream = response.GetResponseStream())
{
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
return content;
}
}
}
} public static string HttpUploadFile(string url, MemoryStream files, string fileName)
{
using (MemoryStream fs = files)
{
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.AllowWriteStreamBuffering = false;
request.SendChunked = true;
request.Method = "POST";
request.Timeout = ; string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); //请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n", fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
request.ContentLength = itemBoundaryBytes.Length + postHeaderBytes.Length + fs.Length + endBoundaryBytes.Length;
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(itemBoundaryBytes, , itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, , postHeaderBytes.Length);
int bytesRead = ; int arrayLeng = fs.Length <= ? (int)fs.Length : ;
byte[] bArr = new byte[arrayLeng];
int counter = ;
fs.Position = ;
while ((bytesRead = fs.Read(bArr, , arrayLeng)) != )
{
counter++;
postStream.Write(bArr, , bytesRead);
}
postStream.Write(endBoundaryBytes, , endBoundaryBytes.Length);
} //发送请求并获取相应回应数据
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//直到request.GetResponse()程序才开始向目标网页发送Post请求
using (Stream instream = response.GetResponseStream())
{
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
return content;
}
}
}
} #region public static 方法 /// <summary>
/// 将请求的流转化为字符串
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public static string GetStr(Stream info)
{
string result = "";
try
{
using (StreamReader sr = new StreamReader(info, System.Text.Encoding.UTF8))
{
result = sr.ReadToEnd();
sr.Close();
}
}
catch
{
}
return result;
} /// <summary>
/// 参数转码
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string stringDecode(string str)
{
return HttpUtility.UrlDecode(HttpUtility.UrlDecode(str, System.Text.Encoding.GetEncoding("UTF-8")), System.Text.Encoding.GetEncoding("UTF-8"));
} /// <summary>
/// json反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="json"></param>
/// <returns></returns>
public static T Deserialize<T>(string json)
{
try
{
T obj = Activator.CreateInstance<T>();
using (MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
return (T)serializer.ReadObject(ms);
}
}
catch
{
return default(T);
}
} #endregion public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{ // 总是接受
return true;
} }
public enum HttpRequestType
{
POST,
GET,
DELETE,
PUT,
PATCH,
HEAD,
TRACE,
OPTIONS
}
然后列出HttpHelper的调用
1、不带参数调用
public bool ConnectServer()
{
try
{
string url = "https://i.cnblogs.com"; string xml = HttpHelper.SendRequest(url, HttpRequestType.POST, null, null, Encoding.UTF8, Encoding.UTF8);
NormalResponse nr = HuaweiXMLHelper.GetNormalResponse(xml);
if (nr.Code == "")
{
HttpHelper.SetHttpCookie(HttpHelper.GetLastCookie());
mIsConnect = true;
return true;
}
else
{
mIsConnect = false;
return false;
}
}
catch (System.Exception ex)
{
mIsConnect = false;
return false;
}
}
2.带参数调用
private bool HandleIntelligentTask(string taskId,bool bStop)
{
try
{
if (!mIsConnect)
{
return false;
}
StringBuilder sb = new StringBuilder();
sb.AppendFormat("<request>\r\n");
sb.AppendFormat("<task_id>{0}</task_id>\r\n", taskId);//<!-- task-id为调用方生成的UUID或其它串 -->
sb.AppendFormat("<status>{0}</status>\r\n",bStop?:);
sb.AppendFormat("</request>\r\n");
string xml = sb.ToString();
string url = mIAServerUrl + "/sdk_service/rest/video-analysis/handle-intelligent-analysis";
string xml2 = HttpHelper.SendRequest(url, HttpRequestType.POST, "text/plain;charset=utf-8", xml, Encoding.UTF8, Encoding.UTF8);
NormalResponse nr = HuaweiXMLHelper.GetNormalResponse(xml2);
if (nr.Code == "")
{
return true;
}
else
{
return false;
}
}
catch (System.Exception ex)
{
return false;
} }
3.异步调用
private void ReStartAlarmServer(List<string> list, string alarmUrl, Thread[] listThread)
{
StopAlarm(alarmUrl, listThread);
listThread[]= new Thread(new ThreadStart(delegate()
{
try
{
if (!mIsConnect)
{
mLog.Error("未登录!--ReStartAlarmServer-结束!");
return;
}
mLog.Info("ReStartAlarmServer开始报警连接....");
if (String.IsNullOrWhiteSpace(alarmUrl)) return;
mLog.InfoFormat("ReStartAlarmServer请求报警:URL={0}", alarmUrl);
string xml = "task-id=0";
string xml2 = HttpHelper.SendRequest(alarmUrl, HttpRequestType.POST, "application/x-www-form-urlencoded", xml, Encoding.UTF8, Encoding.UTF8, AlarmCallBack);
mLog.Info("ReStartAlarmServer报警连接成功!");
}
catch (System.Threading.ThreadAbortException ex)
{
mLog.Info("ReStartAlarmServer线程已人为终止!" + ex.Message, ex);
}
catch (System.Exception ex)
{
mLog.Error("ReStartAlarmServer开始报警连接失败:" + ex.Message, ex);
mLog.Info("ReStartAlarmServer开始重新报警连接....");
mTimes = ;
}
finally
{ }
}));
listThread[].IsBackground = true;
listThread[].Start();
}
private void AlarmCallBack(IAsyncResult ir)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)ir.AsyncState;
string salarmUrl = webRequest.Address.OriginalString;
Thread[] alarmThead = dicAlarmUrls[salarmUrl];
HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse(ir);
Stream stream = response.GetResponseStream();
alarmThead[]= new Thread(new ThreadStart(delegate()
{
try
{
byte[] buffer = new byte[mAlarmReadCount];
int count = ;
string strMsg = "";
int startIndex = -;
int endIndex = -; NormalResponse res = null;
DateTime dtStart = DateTime.Now;
DateTime dtEnd = DateTime.Now;
while (!mIsCloseAlarm)
{
count = stream.Read(buffer, , mAlarmReadCount);
if (count > )
{
strMsg += Encoding.UTF8.GetString(buffer, , count);
startIndex = strMsg.IndexOf("<response>");
endIndex = strMsg.IndexOf("</response>");
string xml = strMsg.Substring(startIndex, endIndex - startIndex + "</response>".Length);
res = HuaweiXMLHelper.GetNormalResponse(xml);
strMsg = strMsg.Substring(endIndex + "</response>".Length);
startIndex = -;
endIndex = -;
break;
}
dtEnd = DateTime.Now;
if ((dtEnd - dtStart).TotalSeconds > )
{
throw new Exception("连接信息未有获取到,需要重启报警!");
}
}
while (!mIsCloseAlarm)
{
count = stream.Read(buffer, , mAlarmReadCount);
if (count > )
{
string temp = Encoding.UTF8.GetString(buffer, , count);
strMsg += temp;
while (strMsg.Length > )
{
if (startIndex == -)//未发现第一个<task-info>
{
startIndex = strMsg.IndexOf("<task-info>");
if (startIndex == -)
{
if (strMsg.Length >= "<task-info>".Length)
{
strMsg = strMsg.Substring(strMsg.Length - "<task-info>".Length);
}
break;
}
}
if (startIndex >= )
{
int i = startIndex + "<task-info>".Length;
int taskInfoEndIndex = strMsg.IndexOf("</task-info>", i);
if (taskInfoEndIndex > )//必须有任务结束节点
{
i = taskInfoEndIndex + "</task-info>".Length;
int i1 = strMsg.IndexOf("</attach-rules>", i);//找到轨迹节点结束
int i2 = strMsg.IndexOf("</alarm>", i);//找到报警节点结束,发现一条报警
if (i1 == - && i2 == -)//没有标志结束
{
break;
}
else if (i1 >= && (i1 < i2 || i2 == -))//找到轨迹结束节点
{
strMsg = strMsg.Substring(i1 + "</attach-rules>".Length);
startIndex = -;
endIndex = -;
continue;
}
else if (i2 > && (i2 < i1 || i1 == -))//找报警节点
{
endIndex = i2;//找到报警节点结束,发现一条报警
string alarmXml = "<taskalarm>" + strMsg.Substring(startIndex, endIndex - startIndex + "</alarm>".Length) + "</taskalarm>"; Thread th = new Thread(new ThreadStart(delegate()
{
ParseAlarmXml(alarmXml);
}));
th.IsBackground = true;
th.Start(); strMsg = strMsg.Substring(endIndex + "</alarm>".Length);
startIndex = -;
endIndex = -;
continue;
}
}
else
{
break;
}
}
}
}
else
{
Console.WriteLine("##########读取报警反馈:无");
Thread.Sleep();
}
}
}
catch (System.Threading.ThreadAbortException ex)
{
mLog.Info("AlarmCallBack...7");
try
{
if (stream != null)
{
stream.Close();
stream.Dispose();
response.Close();
}
}
catch
{
}
mLog.Info("AlarmCallBack线程已人为终止!--0" + ex.Message, ex);
}
catch(IOException ex)
{
mLog.Info("AlarmCallBack...8");
try
{
if (stream != null)
{
stream.Close();
stream.Dispose();
response.Close();
}
}
catch
{
}
}
catch (ObjectDisposedException ex)
{
mLog.Info("AlarmCallBack...9");
mLog.Info("AlarmCallBack读取流已人为终止!--2" + ex.Message, ex);
try
{
if (stream != null)
{
stream.Close();
stream.Dispose();
response.Close();
}
}
catch
{
}
}
catch (System.Exception ex)
{
mLog.Info("AlarmCallBack...10");
mLog.Error("AlarmCallBack 0:" + ex.Message,ex);
try
{
if (stream != null)
{
stream.Close();
stream.Dispose();
response.Close();
}
}
catch
{
} }
finally
{ }
}));
alarmThead[].IsBackground = true;
alarmThead[].Start(); }
catch (System.Exception ex)
{
mLog.Info("AlarmCallBack...11");
mLog.Error("AlarmCallBack 1:" + ex.Message,ex);
mLog.Info("AlarmCallBack开始重新报警连接....3");
mTimes = ;
}
finally
{ }
}
以上就是简单的HttpHelper类的方法使用
HttpHelper类及调用的更多相关文章
- HttpHelper类登录淘宝联盟并下载淘宝客订单xls
本次开发环境与工具如下:IE9.0浏览器 + IE抓包插件HttpWatch +WIN7 64位系统 + VS2005 IDE + .NET 2.0框架本想上传HttpWatch抓包插件,但由于文件超 ...
- [C#HttpHelper]类1.4正式版教程与升级报告
[C#HttpHelper]类1.4正式版教程与升级报告 导读 1.升级报告 2.HttpHelper1.4正式版下载 3.HttpHelper类使用方法, 4.最简单的Post与Get的写法 ...
- HttpWebRequest 模拟登录响应点击事件(分享自己用的HttpHelper类)
平时也经常采集网站数据,也做模拟登录,但一般都是html控件POST到页面登录:还没有遇到用户服务器控件button按钮点击事件登录的,今天像往常一样POST传递参数,但怎么都能登录不了:最后发现还有 ...
- Java、C#双语版HttpHelper类
Java.C#双语版HttpHelper类(解决网页抓取乱码问题) 在做一些需要抓取网页的项目时,经常性的遇到乱码问题.最省事的做法是去需要抓取的网站看看具体是什么编码,然后采用正确的编码进行解码 ...
- 类间调用inline函数的效率
问题描述: class A { public: int x, y, k, NY; inline int f(int i, int j, int k) {return ((i)*(NY + 1) * ...
- 不错的 HttpHelper类 c#
/// <summary>/// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理/// 重要提示: ...
- Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)
当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...
- php -- 类对象调用静态方法
以前一直以为 静态方法的调用:类名::静态方法 非静态方法的调用:类对象->非静态方法 最近研究一个类,发现一个比较奇怪的问题,用“类对象->静态方法”这种方式居然成功的调用了静态方法.很 ...
- spring管理的类如何调用非spring管理的类
spring管理的类如何调用非spring管理的类. 就是使用一个spring提供的感知概念,在容器启动的时候,注入上下文即可. 下面是一个工具类. import org.springframewor ...
随机推荐
- BZOJ1208_宠物收养所_KEY
题目传送门 平衡树的题. 因为题目给出条件(其实自己也知道):同一时间呆在收养所中的,要么全是宠物,要么全是领养者,这些宠物和领养者的个数不会超过10000个. 所以只要维护一颗平衡树,它的里面要不全 ...
- Zabbix学习之路(六)TCP状态监控
TCP状态监控 Tcp的连接状态对于我们web服务器来说是至关重要的,尤其是并发量ESTAB:或者是syn_recv值,假如这个值比较大的话我们可以认为是不是受到了***,或是是time_wait值比 ...
- Python小白学习之函数装饰器
装饰器 2018-10-25 13:49:37 装饰器从字面意思就是用来装饰的,在函数可以理解为:在函数中,我们不想影响原来的函数功能,又想给函数添加新的功能,这时候我们就用到了装饰器. 一般函数操作 ...
- Java 验证码识别库 Tess4j 学习
Java 验证码识别库 Tess4j 学习 [在用java的Jsoup做爬虫爬取数据时遇到了验证码识别的问题(基于maven),找了网上挺多的资料,发现Tess4j可以自动识别验证码,在这里简单记录下 ...
- TW实习日记:第十天
今天任务很简单,就是出品项目的时间轴显示页面和动态路由设置.其实时间轴页面很快就做完了,在做完处理完数据之后,然而有很多细节需要打磨,这就又考验了我面向搜索引擎编程的能力,根据需求百度了很多css的样 ...
- 【MySQL 数据库】MySQL目录
目录 [第一章]MySQL数据概述 [第二章]MySQL数据库基于Centos7.3-部署 [MySQL解惑笔记]Centos7下卸载彻底MySQL数据库 [MySQL解惑笔记]忘记MySQL数据库密 ...
- Python多重赋值
可以将变量名视对象的一个链接 >>>foo1 = foo2 = 4.3 >>>foo1 is foo2 True >>>foo1 = 4.3 &g ...
- 基于kcp,consul的service mesh实现
名字kmesh 技术:proxy,kcp,consul proxy proxy分为前端和后端 前端代理服务层,包括外部的service 后端实现负债均衡 kcp kcp 基于udp,能够实现快速的传输 ...
- javascript中的取反再取反~~
操作符~, 是按位取反的意思,表面上~~(取反再取反)没有意义,实际上在JS中可以将浮点数变成整数. <html> <script> var myArray = new Arr ...
- Python爬虫入门(1-2):综述、爬虫基础了解
大家好哈,最近博主在学习Python,学习期间也遇到一些问题,获得了一些经验,在此将自己的学习系统地整理下来,如果大家有兴趣学习爬虫的话,可以将这些文章作为参考,也欢迎大家一共分享学习经验. Pyth ...