孵蛋机
前言
无数不成体系的养料都在这里,等待成为一个蛋,等待被孵化。
GDI绘图(C#)
C#中使用GDI绘图,需要using System.Drawing;
-
GDI简单绘图
想要绘制图形,首先需要有承载图形的画板和用于绘图的画笔。
//创建GDI对象 Graphics graphics = this.CreateGraphics(); //创建画笔对象 Pen pen = new Pen(Brushes.Red);
绘制直线
//创建两个点 Point p1 = new Point(30, 50); Point p2 = new Point(100, 100); //绘制线 graphics.DrawLine(pen,p1,p2);
绘制矩形
Size size = new Size(140, 50); Rectangle rec = new Rectangle(new Point(130, 50), size); graphics.DrawRectangle(pen, rec);
绘制扇形
Size size = new Size(140, 140); Rectangle rec = new Rectangle(new Point(280, 0), size); graphics.DrawPie(pen,rec,60,60);
绘制字符串
graphics.DrawString( "要绘制的字符串", new Font("宋体",20,FontStyle.Bold), Brushes.Black, new Point(430,50));
绘制指定图片
graphics.DrawImage( Image.FromFile(@"这是图片路径"), x, y, width, height);
-
GDI绘图时消除闪烁现象(使用双缓冲)
当所需绘制的图形过多且希望部分图片移动时,界面往往由于不断对图形进行绘制,且由于所有待绘制图形不能同时绘制,因此会出现部分图形先出现,部分图形后出现的现象,再加上刷新频率较快,因此导致闪烁。
消除闪烁的方法很简单,只需我们将图形全部先绘制在虚拟画布上(而不是直接绘制在窗体上),在一次绘制完成后,再将该画布内容一次性画到窗体上,就能够避免闪烁现象。这一方法也叫做双缓冲技术。
为了实现这一技术,我们首先需要在相应窗体的InitializeComponent()中加入:
this.DoubleBuffered = true;//双缓冲
以此开启开窗体的双缓冲。
接着需要创建一张虚拟画布,并将所有待绘制图形全部绘制到该虚拟画布上:
//建立虚拟画布 Bitmap bitp = new Bitmap(this.Width, this.Height); //将所有绘图操作绑定在虚拟画布上 Graphics g = Graphics.FromImage(bitp); //开始绘图 ...... //所有待绘制图形绘制完毕后,将虚拟画布上的内容绘制到窗体 this.CreateGraphics().DrawImage(bitp, 0, 0); //单次绘图完毕后释放绘制资源 g.Dispose(); //释放虚拟画布资源 bitp.Dispose();
至此,就通过使用双缓冲解决了GDI窗体绘图闪烁问题。
至于窗体内控件使用过多导致窗体闪烁的问题,将通过另一方式实现,即在窗体的InitializeComponent()中加入一些代码,这里不再细说,有需要可以网上搜搜(绝对
不是因为我太懒才不写的!)
HTTP协议
希望能够使用HTTP进行信息传递
HTTP请求/相应步骤:
-
客户端连接到Web服务器:
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。
-
发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
-
服务器接收请求并返回HTTP相应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。
-
释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求。
-
客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。
HTTP协议是基于TCP/IP协议之上的应用层协议
HTTP请求方法
HTTP/1.1协议中定义了8种方法,通过8种不同的方式操作指定的资源:
-
GET:获取资源
GET方法用来请求已被URI(URI与URL的区别见下方)识别的资源。指定的资源经服务器端解析后返回响应内容(也就是说,如果请求的资源是文本,那就保持原样返回;如果是CGI[通用网关接口]那样的程序,就返回经过执行后的输出结果)。
该方法最常用于向服务器查询某些信息。
URI与URL的区别
URI表示的是web上每一种可用的资源,比如说HTML文档、图像、视频片段、程序等都是由一个URI进行标识的。而URL是URI的一个子集,采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL是URI概念的一种实现方式。
区别:URI是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。
比如:URI:http://www.123.com/123/,该目录下可能有index.html和index.htm两个文件;而URL:http://www.123.com/123/index.html,则唯一指向一个文件。
-
POST:传输实体文本
POST方法用来传输实体的主体。
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。
-
HEAD:获得报文首部
HEAD方法与GET方法一样,只是不会返回报文的主体部分(向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分)。其好处在于可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。
-
PUT:传输文件
向指定资源位置上传其最新内容。
PUT方法用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存在请求URI指定的位置。
-
DELETE:删除文件
指明客户端想让服务器删除某个资源,与PUT方法相反,按URI删除指定资源。
-
OPTIONS:询问支持的方法
OPTIONS方法用来查询针对请求URI指定资源支持的方法(客户端询问服务器可以提交哪些请求方法)。
-
TRACE:追踪路径
客户端可以对请求消息的传输路径进行追踪,TRACE方法是让Web服务器端将之前的请求通信还给客户端的方法。
-
CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL(安全套接层)和TLS(传输层安全)协议把通信内容加密后经网络隧道传输。
HTTP请求格式(请求协议)
HTTP相应格式(响应协议)
使用HTTP协议向服务器接口/网站上传文件
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace HttpTest
{
public class HttpUploadFile
{
/// <summary>
/// Http上传文件
/// </summary>
public static string httpUploadFile(string url, string path)
{
//
// 设置参数
//
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
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 + 1);//从字符串指定位置一直读取到字符串末尾
//
//请求头部信息
//
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());
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] bArr = new byte[fs.Length];
fs.Read(bArr, 0, bArr.Length);
fs.Close();
Stream postStream = request.GetRequestStream();
postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
postStream.Write(bArr, 0, bArr.Length);
postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
postStream.Close();
//
//发送请求并获取相应回应数据
//
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//
//直到request.GetResponse()程序才开始向目标网页发送Post请求
//
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//
//返回结果网页(html)代码
//
string content = sr.ReadToEnd();
return content;
}
}
}
C#
-
打开文件对话框
——迁移至《面向快乐的C#编程》·C#文件操作
-
Action(()=>{代码;})
第一眼看到这个代码还是一脸懵比的,不知道是在干啥,接着就去百度查了一下。下面是对这些代码的一个理解。
首先,这是一个简写形式,这种简写是lambda表达式。这个简写形式还原后,其实就是一个匿名委托。
()=>{代码;}
这个表达式,最前面的小括号内()是委托使用的参数,大括号{}内是委托方法的具体实现,这里的小括号为空,也就是说这个委托的参数为空,这就是封装了一个不包含任何参数的方法。把它换成一般的委托定义就是:delegate void CommonDelegate();
而匿名函数并不具备类型,因此需要进行强制转换,所以在前面加上了Action,表示将匿名方法转换成标注的委托类型。Action是.NET自定义的委托,表示一个不接受任何参数的委托方法。
至此,就能够把这个简写形式还原为完整的写法了:
Action (delegate(){ //匿名委托中要做的事情 //... });
现在大家都是产品经理了
记录生活中的奇思妙想
-
桌面备忘工具
-
桌宠+AI=女儿