http3協定是架構在以往被認為最不穩定的UDP基礎上,而為了消除UDP的不確定性,加上了QUIC協定。
透過QUIC來替代TCP對於可靠以及流量的控制,使得http3可以有效可靠的進行傳輸。
在.net 6的preview版本中,微軟也加上了對http/3的支援,也許它會是http協定的一估新的未來
大型網站架構..net 架構師.rabbitMQ.redis.行動開發.APP開發教學.PHP Laravel開發..net core C# 開發.架構師之路.Delphi開發.資料庫程式.進銷存.餐飲POS系統
http3協定是架構在以往被認為最不穩定的UDP基礎上,而為了消除UDP的不確定性,加上了QUIC協定。
透過QUIC來替代TCP對於可靠以及流量的控制,使得http3可以有效可靠的進行傳輸。
在.net 6的preview版本中,微軟也加上了對http/3的支援,也許它會是http協定的一估新的未來
最近在測試,如果透過web申請帳號後,可不可以直接在DNS上一增子網域以及在IIS上增加站台的方式,直接申請後就有站台,在Windows 的網站主機上,似乎要透過appcmd與dnscmd達到。後來弄出了一個可以執行的方式,主要重點在於要有較高權限的帳密透過process執行cmd模式再去下指令。分享一下
/// <summary>
/// 新增IIS站台
/// </summary>
/// <param name=”subdomain”>網站名稱</param>
/// <param name=”domain”>網域</param>
/// <param name=”webpath”>網頁位置</param>
/// <returns></returns>
public bool AddSite(string subdomain, string domain, string webpath)
{
using (Process p = new Process())
{
p.StartInfo.FileName = @”cmd.exe”;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UserName = “高權限帳號”;
string pw = “高權限密碼”;
SecureString ss = new SecureString();
foreach (char c in pw)
{
ss.AppendChar(c);
}
p.StartInfo.Password = ss;
//
p.StartInfo.Arguments = “/c appcmd add site /name:”+subdomain+” /bindings:\”http/*:80:”+subdomain+”.”+domain+”,https/*:443:”+subdomain+”.”+domain+”\” /physicalPath:\””+webpath+”\””;
p.Start();
p.WaitForExit();
StreamReader sr = p.StandardOutput;
p.Close();
string message = sr.ReadToEnd().Replace(“\n”, “<br />”);
if (message.Contains(“ERROR”))
{
return false;
}
else
{
return true;
}
}
}
/// <summary>
/// 透過指令新增子網域(如: levin.ksi.com.tw)
/// </summary>
/// <param name=”subdomain”>子網域名稱</param>
/// <param name=”domain”>主網域</param>
/// <param name=”ip”>主機IP</param>
/// <returns></returns>
public bool AddDNS(string subdomain,string domain,string ip)
{
using (Process p = new Process())
{
p.StartInfo.FileName = @”cmd.exe”;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.UserName = “高權限帳號”;
string pw = “高權限密碼”;
SecureString ss = new SecureString();
foreach (char c in pw)
{
ss.AppendChar(c);
}
p.StartInfo.Password = ss;
p.StartInfo.Arguments = @”/c dnscmd /recordadd ” + domain + ” ” + subdomain + ” A ” + ip;
p.Start();
p.WaitForExit();
StreamReader sr = p.StandardOutput;
p.Close();
string message = sr.ReadToEnd().Replace(“\n”, “<br />”);
if (message.Contains(“成功”)){
return true;
}
else
{
return false;
}
}
}
使用asp.net core 開發LINE BOT時,使用ngrok做本機的服務器時,驗證Webhook出現錯誤。ngrok出現 307 Temporary Redirect的錯誤!
解決方式:
Starup.cs中有一句app.UseHttpsRedirection(); 前面加上 // 註解掉就可以了
參考:
ngrok http [port] -host-header="localhost:[port]"
最近常遇到需要使用AES加解密的需求,無論是網路傳輸/API相關的部份。
分享一下
Github原始碼下載
https://github.com/superlevin/CSharpAES
using System.Security.Cryptography;
public static string SHAEncrypt(string str)
{
var crypt = new System.Security.Cryptography.SHA256Managed();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(str));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
// x小寫 X 大寫 x2 補0
}
return hash.ToString();
}
public static string AESEncrypt(string str, string strkey, string strivKey, bool isVasEncrypt = false)
{
var aesCipher = new AesManaged
{
KeySize = 128,
BlockSize = 128,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
var keyStr = KeyGenerator(strkey);
var key = Convert.FromBase64String(keyStr);
var ivKey = Encoding.UTF8.GetBytes(strivKey);
var input = str;
var ivStr = Convert.ToBase64String(ivKey);
aesCipher.Key = key;
aesCipher.IV = ivKey;
byte[] b = System.Text.Encoding.UTF8.GetBytes(str); // plain text to be encrypted
ICryptoTransform encryptTransform = aesCipher.CreateEncryptor();
byte[] cipherText = encryptTransform.TransformFinalBlock(b, 0, b.Length);
return Convert.ToBase64String(cipherText);
}
public static string AESDecrypt(string encstring, string strkey, string strivKey)
{
var aesCipher = new AesManaged
{
KeySize = 128,
BlockSize = 128,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
};
var keyStr = KeyGenerator(strkey);
var key = Convert.FromBase64String(keyStr);
aesCipher.Key = key;
aesCipher.IV = Encoding.UTF8.GetBytes(strivKey);
var encryptBytes = Convert.FromBase64String(encstring);
ICryptoTransform decryptTransform = aesCipher.CreateDecryptor();
byte[] plainText = decryptTransform.TransformFinalBlock(encryptBytes, 0, encryptBytes.Length);
return System.Text.Encoding.UTF8.GetString(plainText);
}
短短12分鐘的影片,由微軟介紹新版本visual studio 2017如何快速使用asp.net core與entity framework core開發。在影片中會發現entity framework API改進
[C#]
DataSet FDataSet;
// 建立資料集
FDataSet = new DataSet();
DataTable table = new DataTable();
table.TableName = “Employees”;
FDataSet.Tables.Add(table);
table.Columns.Add(“ID”, typeof(int));
table.Columns.Add(“Name”, typeof(string));
table.Rows.Add(1, “Andrew Fuller”);
table.Rows.Add(2, “Nancy Davolio”);
table.Rows.Add(3, “Margaret Peacock”);
// 建立報表
Report report = new Report();
// 載入報表
report.Load(@”..\..\report.frx”);
// 註冊資料集
report.RegisterData(FDataSet);
report.GetDataSource(“Employees”).Enabled = true;
// 1 進入設計模式
report.Design();
// 2 顯示報表
report.Show();
// 3 匯出成pdf
report.Prepare();
PDFExport export = new PDFExport();
report.Export(export, “result.pdf”);
report.Dispose();
[/c#]
[C#]
FontStyle fs =labelMSG.Font.Style;
FontFamily fm = new FontFamily(labelMSG.Font.Name);
Font f = new Font(fm, fontsize, fs);
labelMSG.Font = f;
[/C#]
Embarcadero官方訊息釋出2016年的Roadmap,
在國外行之有年的取餐呼叫器(Pager)最近也在台灣風行起來,看到了二款取餐呼叫器,一個是國產亞克高科(ARCT)由銥特爾科技(02-29974000)代理,一個是韓國(Syscall)製造由鋐鈦科技代理。
二款都可以透過COM PORT設定~~ 以Delphi以及C#針對韓國的做範例。
Delphi
var iPagerno :Integer; sStr,s :AnsiString; begin Try Pager_COM.StopComm; // 先將Pager Com關閉 Pager_COM.CommName := ComName; Pager_COM.StartComm; Sleep(50); //開啟COM需等待 iPagerno := StrToIntDef(PagerNo,1); sStr := copy(IntToStr(iPagerno),1,4) s:= Ansichar(#開始指令)+sStr+Ansichar(#結束指令); Pager_COM.WriteCommData(PAnsiChar(s),Length(s)); Except End;
C#
public void Pager_Send(String COMName,String PagerNo) { public static System.IO.Ports.SerialPort PAGERPORT = new System.IO.Ports.SerialPort(); byte[] PAGERSTART = { 開始指令 }; byte[] PAGEREND = { 結束指令 }; try { if (PAGERPORT.IsOpen) PAGERPORT.Close(); PAGERPORT.PortName = COMName; PAGERPORT.BaudRate = 9600; PAGERPORT.Parity = System.IO.Ports.Parity.None; PAGERPORT.DataBits = 8; PAGERPORT.StopBits = System.IO.Ports.StopBits.One; PAGERPORT.Open(); if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PAGERSTART.Length; i++) { PAGERPORT.Write(PAGERSTART , i, 1); } PagerNo = PagerNo.PadLeft(4, '0').ToString(); byte[] PagerNoData= Encoding.Default.GetBytes(PagerNo); if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PagerNoData.Length; i++) { PAGERPORT.Write(PagerNoData, i, 1); } if (!PAGERPORT.IsOpen) PAGERPORT.Open(); for (int i = 0; i < PAGEREND .Length; i++) { PAGERPORT.Write(PAGEREND , i, 1); } } catch { return; } }
Delphi或C#與信用卡連接的方式,有直接透過com port通訊或是透過呼叫exe的方式,利用in.txt、out.txt做溝通。然後回傳信用卡卡號/授權碼/刷卡金額等資訊。
示範一下Delphi與C#如何做信用卡線上刷卡。
Delphi
public { Public declarations } ExecInfo : TShellExecuteInfo; // use shellapi i:integer; end; procedure TForm1.Button1Click(Sender: TObject); var s:String; ts:TStringlist; begin ZeroMemory(@ExecInfo,SizeOf(ExecInfo)); with ExecInfo do begin cbSize := SizeOf(ExecInfo); fMask := SEE_MASK_NOCLOSEPROCESS; lpVerb := 'open'; lpFile := 'ecr.exe'; Wnd := self.Handle; nShow := SW_HIDE; end; s:='xxxxxxxxxxxxxxxxxxxx'; // 填上信用卡的溝通格式 ts := Tstringlist.Create; ts.Clear; ts.Add(s); ts.SaveToFile('in.dat'); ts.Free; ShellExecuteEx(@ExecInfo); deletefile('out.dat'); caption := '刷卡中...'; timer1.Enabled := True; i:=0; end; procedure TForm1.Timer1Timer(Sender: TObject); var ts1:Tstringlist; sstatus,smoney,scard,sappno:String; begin i:=i+1; if fileexists('out.dat') then begin Timer1.Enabled := false; ts1 := Tstringlist.Create; ts1.LoadFromFile('out.dat'); if ts1.Count >0 then begin // 讀入檔案,解析格式 end; ts1.Free; end; end;
string dir = System.Windows.Forms.Application.StartupPath; [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); private void uForm1_Load(object sender, EventArgs e) { try { if (File.Exists(dir + "/out.txt")) //刪除out.txt File.Delete(dir + "/out.txt"); string code = ""; // in.txt格式 using (StreamWriter sw = new StreamWriter(dir + "/in.txt")) //小寫TXT sw.Write(code); IntPtr PDC = FindWindow(null, "ecr"); //開啟PosDataCom if (PDC == (IntPtr)0) { try { Process p = new Process(); p.StartInfo.FileName = dir + "/ecrnccc.exe"; p.StartInfo.WorkingDirectory = dir; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.Start(); } catch (Exception exp) { return; } } this.timer1.Enabled = true; } catch (Exception ex) { throw new Exception(ex.Message); } } private void timer1_Tick(object sender, EventArgs e) { if (times == 5) { times = 0; i++; if (i > 4) { i = 0; try { if (File.Exists(dir + "/out.txt")) { using (StreamReader sr = new StreamReader(dir + "/out.txt")) //小寫TXT { String line; if ((line = sr.ReadLine()) != null) { // 解析 } else return false; return true; } } return false; } catch { return false; } } } times++; }