您现在的位置是:网站首页> C#技术
C#学习笔记
- C#技术
- 2024-07-21
- 1289人已阅读
C#学习笔记
WinForm 嵌入第三方程序窗体(WinForm 嵌入 ffplay 窗体)
C#创建windows任务计划程序2种方法(兼容win7、win10)
Unity 3D的UGUI库,点击查看介绍
C# 使用Microsoft Edge WebView2的相关总结
设置ASP.NET上传文件大小
修改web.config
<httpRuntime maxRequestLength="102400" maxQueryStringLength="102400" useFullyQualifiedRedirectUrl="true" requestValidationMode="2.0" />
</system.web>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1048576000">
</requestLimits>
</requestFiltering>
</security>
</system.webServer>
字符串数组按字母排序
static public string GetHashOrderString(Hashtable m_Data)
{
ArrayList akeys = new ArrayList(m_Data.Keys); //别忘了导入System.Collections
akeys.Sort(StringComparer.Ordinal); //按字母顺序进行排序
string dataString = "{";
foreach (string skey in akeys)
{
Post XML
项目分成两个 web(ASP.Net)用户处理请求,客户端(wpf/winform)发送请求
1.web项目
有两个页面
SendPost.aspx(单纯发送数据给客户端)
代码:
public partial class SendPost : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Request.RequestType == "POST")
{
//声明一个XMLDoc文档对象,LOAD()xml字符串
XmlDocument doc = new XmlDocument();
doc.LoadXml("<entity><version>1.2.0_2012_12_05</version></entity>");
//把XML发送出去
Response.Write(doc.InnerXml);
Response.End();
}
}
}
Accept.aspx(接收数据并反馈发送会客户端)
protected void Page_Load(object sender, EventArgs e)
{
if (Request.RequestType == "POST")
{
//接收并读取POST过来的XML文件流
StreamReader reader = new StreamReader(Request.InputStream);
String xmlData = reader.ReadToEnd();
//把数据重新返回给客户端
Response.Write(xmlData);
Response.End();
}
}
2.客户端项目:
一个处理Post类
public class PostHelp
{
public string GetWebContent(string url)
{
Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
// 要注意的这是这个编码方式,还有内容的Xml内容的编码方式
Encoding encoding = Encoding.GetEncoding("UTF-8");
byte[] data = encoding.GetBytes(url);
// 准备请求,设置参数
request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "text/xml";
//request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, 0, data.Length);
outstream.Flush();
outstream.Close();
//发送请求并获取相应回应数据
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
return content;
}
public string PostXml(string url, string strPost)
{
string result = "";
StreamWriter myWriter = null;
HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
objRequest.Method = "POST";
//objRequest.ContentLength = strPost.Length;
objRequest.ContentType = "text/xml";//提交xml
//objRequest.ContentType = "application/x-www-form-urlencoded";//提交表单
try
{
myWriter = new StreamWriter(objRequest.GetRequestStream());
myWriter.Write(strPost);
}
catch (Exception e)
{
return e.Message;
}
finally
{
myWriter.Close();
}
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
using (StreamReader sr = new StreamReader(objResponse.GetResponseStream()))
{
result = sr.ReadToEnd();
sr.Close();
}
return result;
}
}
一个XML处理类
public class XMLHelp
{
private XDocument _document;
public XDocument Document
{
get { return _document; }
set { _document = value; }
}
private string _fPath = "";
public string FPath
{
get { return _fPath; }
set { _fPath = value; }
}
/// <summary>
/// 初始化数据文件,当数据文件不存在时则创建。
/// </summary>
public void Initialize()
{
if (!File.Exists(this._fPath))
{
this._document = new XDocument(
new XElement("entity", string.Empty)
);
this._document.Save(this._fPath);
}
else
this._document = XDocument.Load(this._fPath);
}
public void Initialize(string xmlData)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlData);
this._document = XmlDocumentExtensions.ToXDocument(doc, LoadOptions.None);
}
/// <summary>
/// 清空用户信息
/// </summary>
public void ClearGuest()
{
XElement root = this._document.Root;
if (root.HasElements)
{
XElement entity = root.Element("entity");
entity.RemoveAll();
}
else
root.Add(new XElement("entity", string.Empty));
}
///LYJ 修改
/// <summary>
/// 提交并最终保存数据到文件。
/// </summary>
public void Commit()
{
try
{
this._document.Save(this._fPath);
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
/// <summary>
/// 更新
/// </summary>
public void UpdateQrState(string PId, string state)
{
XElement root = this._document.Root;
XElement entity = root.Element("entity");
IEnumerable<XElement> elements = entity.Elements().Where(p =>
p.Attribute("PId").Value == PId);
if (elements.Count() == 0)
return;
else
{
XElement guest = elements.First();
guest.Attribute("FQdState").Value = state;
guest.Attribute("FQdTime").Value = DateTime.Now.ToString();
Commit();
}
}
public IEnumerable<XElement> GetXElement()
{
XElement root = this._document.Root;
IEnumerable<XElement> elements = root.Elements();
return elements;
}
public DataTable GetEntityTable()
{
DataTable dtData = new DataTable();
XElement root = this._document.Root;
IEnumerable<XElement> elements = root.Elements();
foreach (XElement item in elements)
{
dtData.Columns.Add(item.Name.LocalName);
}
DataRow dr = dtData.NewRow();
int i = 0;
foreach (XElement item in elements)
{
dr[i] = item.Value;
i = i + 1;
}
dtData.Rows.Add(dr);
return dtData;
}
}
因为我这里用的是Linq操作XML所以多一个转换XML类
public static class XmlDocumentExtensions
{
public static XDocument ToXDocument(this XmlDocument document)
{
return document.ToXDocument(LoadOptions.None);
}
public static XDocument ToXDocument(this XmlDocument document, LoadOptions options)
{
using (XmlNodeReader reader = new XmlNodeReader(document))
{
return XDocument.Load(reader, options);
}
}
}
客户端加个按钮,按钮代码
private void button5_Click(object sender, RoutedEventArgs e)
{
PostHelp ph = new PostHelp();
//请求,拿到数据
string value = ph.GetWebContent("http://192.168.52.24:802/SendPost.aspx");
//保存数据
XMLHelp xh = new XMLHelp();
xh.Document = XDocument.Parse(value);
xh.FPath = Environment.CurrentDirectory + "\\xml\\a.xml";
xh.Commit();
//重新把数据拿出来,发送
string a = xh.Document.ToString();
string text = ph.PostXml("http://192.168.52.24:802/Accept.aspx", a);
//根据得到数据显示
this.textBlock1.Text = text;
//把数据转换成DataTable,输出要的结果集
DataTable dt = xh.GetEntityTable();
MessageBox.Show(dt.Rows[0][0].ToString());
}
代码很多,思路虽然有写在注释里,但是还是不够清楚,我这里重新说一下
1.首先是Post请求发送原理,客户端请求一个request,并把内容加到request中,发送到指定路径的页面,页面得到请求,返回数据,客户端再基于刚刚的request去GetResponse()得到返回数据
2.另外一个是XML的操作,包括读取xml,把xml转成字符串用于发送,得到返回内容,保存到本地xml,再读取本地的xml,输出xml里面的值
WinForm 嵌入第三方程序窗体(WinForm 嵌入 ffplay 窗体)
ffplay 播放功能强大, 把它嵌入 winform 可很容易的实现一个播放器.
找到 ffplay 窗体句柄, 分别调用 SetParent 和 ShowWindow 两个 windows api 即可把 ffplay 的窗体,嵌入到 winform 的 panel 控件中。
示例代码如下:
public Form1()
{
InitializeComponent();
}
[DllImport("user32.dll", EntryPoint = "SetParent")]
public static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll ", EntryPoint = "ShowWindow")]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
private void button1_Click(object sender, EventArgs e)
{
Process ffplay = Process.GetProcessesByName("ffplay").FirstOrDefault();
if (ffplay == null)
{
MessageBox.Show("没找到进程");
return;
}
SetParent(ffplay.MainWindowHandle, this.panel1.Handle);
ShowWindow(ffplay.MainWindowHandle, 3);//第一个参数窗口句柄,第二个参数 指定窗口如何显示
}
}
C#创建windows任务计划程序2种方法(兼容win7、win10)
一:NuGet中搜索包:Microsoft.Win32.TaskScheduler并引用:
public static void RunTaskService(string vbsRootPath)
{
string taskName = "HelperTray1";
TaskService ts = new TaskService();
Microsoft.Win32.TaskScheduler.Task wsTask = ts.GetTask(taskName);
if (wsTask == null)
{
string vbsStart = Path.Combine(vbsRootPath, "Start.vbs");//ApiConfig.ExtPath
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = taskName;
//开机后2分钟开始运行任务
//td.Triggers.Add(new BootTrigger { Delay = new TimeSpan(0, 2, 0) });
//参数1 Interval 间隔:每次重新启动任务之间的时间量。允许的最长时间为31天,允许的最短时间为1分钟
//参数2 Duration 持续时间:重复模式的持续时间。允许的最短时间是一分钟。如果指定了TimeSpan.Zero,则该模式将无限期地重复。
//参数3:获取或设置一个布尔值,该值指示正在运行的任务实例在重复模式持续时间结束时停止。
RepetitionPattern repetition = new RepetitionPattern(new TimeSpan(0, 1, 0), TimeSpan.Zero, true);
td.Triggers.Add(new DailyTrigger { Repetition = repetition });
td.Actions.Add(new ExecAction("wscript.exe", vbsStart, null));
ts.RootFolder.RegisterTaskDefinition(taskName, td);
}
}
二、在系统C:WindowsSystem32 下查找DLL:taskschd.dll并引用到项目中:
public static void CreateTaskScheduler(string vbsRootPath)
{
try
{
LogEvent.LogInfo.Fatal("2创建计划任务:1");
string taskName = "HelperTray2";
TaskSchedulerClass scheduler = new TaskSchedulerClass();
//pc-name/ip,username,domain,password
scheduler.Connect(null, null, null, null);
ITaskFolder folder = scheduler.GetFolder("\");
IRegisteredTask rt = null;
try
{
//搜索不到会抛异常
rt = folder.GetTask(taskName);
if (rt != null)
return;
}
catch(Exception ex)
{
LogEvent.LogInfo.Info("任务计划程序不存在,创建:");
}
LogEvent.LogInfo.Fatal("2创建计划任务:2");
//set base attr
ITaskDefinition task = scheduler.NewTask(0);
//task.RegistrationInfo.Author = "system";//creator
task.RegistrationInfo.Description = taskName;
//set trigger (IDailyTrigger ITimeTrigger) 设置小时/分/秒来实现
// ITimeTrigger tt = (ITimeTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME);
// tt.Repetition.Interval = interval;// format PT1H1M==1小时1分钟 设置的值最终都会转成分钟加入到触发器
//设置每天特定的时间来实现
IDailyTrigger tt = (IDailyTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_DAILY);
tt.StartBoundary = string.Format("1970-05-01T{0}:00:00", "04");
tt.EndBoundary = string.Format("2100-05-01T{0}:00:00", "04");
//tt.Repetition= new RepetitionPattern
//start time //set action
IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
action.Path = "wscript.exe";
string vbsStart = Path.Combine(vbsRootPath, "HelperStart.vbs");//ApiConfig.ExtPath
action.Arguments = vbsStart;//运行程序时需要的参数,如果没有可以不写。
task.Settings.ExecutionTimeLimit = "PT0S"; //运行任务时间超时停止任务吗? PTOS 不开启超时
task.Settings.DisallowStartIfOnBatteries = false;//只有在交流电源下才执行
task.Settings.RunOnlyIfIdle = false;//仅当计算机空闲下才执行
IRegisteredTask regTask = folder.RegisterTaskDefinition(taskName, task, (int)_TASK_CREATION.TASK_CREATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
IRunningTask runTask = regTask.Run(null);
//return runTask.State;
LogEvent.LogInfo.Fatal("2创建计划任务:3");
}
catch (Exception ex)
{
LogEvent.LogInfo.Fatal("创建计划任务异常:"+ex);
//throw ex;
}
}
C#实现Web服务器
一般实现
using System;
using System.Net;
using System.Threading;
namespace YourNamespace
{
class Program
{
static void Main(string[] args)
{
// 定义服务器地址和端口
string url = "http://localhost:8080/";
// 创建HttpListener对象
HttpListener listener = new HttpListener();
listener.Prefixes.Add(url);
// 启动监听
listener.Start();
Console.WriteLine("Web服务器正在运行...");
// 处理请求
while (true)
{
// 接收传入的请求
HttpListenerContext context = listener.GetContext();
// 处理请求逻辑
ThreadPool.QueueUserWorkItem((_) =>
{
// 获取请求信息
HttpListenerRequest request = context.Request;
// 构建响应内容
string responseString = "Hello, World!";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// 设置响应头
context.Response.ContentLength64 = buffer.Length;
// 发送响应内容
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
});
// 关闭请求
context.Response.Close();
}
}
}
}
.NET4.5实现稳定的web服务器
using System;
using System.Net;
using System.Threading;
namespace YourNamespace
{
class Program
{
static void Main(string[] args)
{
// 定义服务器地址和端口
string url = "http://localhost:8080/";
// 创建HttpListener对象
HttpListener listener = new HttpListener();
listener.Prefixes.Add(url);
// 启动监听
listener.Start();
Console.WriteLine("Web服务器正在运行...");
// 处理请求
while (true)
{
try
{
// 接收传入的请求
HttpListenerContext context = listener.GetContext();
// 使用线程池处理请求
ThreadPool.QueueUserWorkItem((_) => ProcessRequest(context));
}
catch (Exception ex)
{
Console.WriteLine($"处理请求时出现错误: {ex.Message}");
}
}
}
static void ProcessRequest(HttpListenerContext context)
{
try
{
// 获取请求信息
HttpListenerRequest request = context.Request;
// 构建响应内容
string responseString = "Hello, World!";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// 设置响应头
context.Response.ContentLength64 = buffer.Length;
// 发送响应内容
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
}
catch (Exception ex)
{
Console.WriteLine($"处理请求时出现错误: {ex.Message}");
}
finally
{
// 关闭请求
context.Response.Close();
}
}
}
}
稳定可靠的代码
using System;
using System.Net;
using System.Threading.Tasks;
namespace YourNamespace
{
class Program
{
static void Main(string[] args)
{
// 定义服务器地址和端口
string url = "http://localhost:8080/";
// 创建HttpListener对象
HttpListener listener = new HttpListener();
listener.Prefixes.Add(url);
// 启动监听
listener.Start();
Console.WriteLine("Web服务器正在运行...");
// 处理请求
while (true)
{
try
{
// 接收传入的请求
HttpListenerContext context = listener.GetContext();
// 使用异步任务处理请求
Task.Run(() => ProcessRequestAsync(context));
}
catch (Exception ex)
{
Console.WriteLine($"处理请求时出现错误: {ex.Message}");
}
}
}
static async Task ProcessRequestAsync(HttpListenerContext context)
{
try
{
// 获取请求信息
HttpListenerRequest request = context.Request;
// 构建响应内容
string responseString = "Hello, World!";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// 设置响应头
context.Response.ContentLength64 = buffer.Length;
// 发送响应内容
await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
}
catch (Exception ex)
{
Console.WriteLine($"处理请求时出现错误: {ex.Message}");
}
finally
{
// 关闭请求
context.Response.Close();
}
}
}
}
```
XML操作
创建xml文档创建xml文档
public void CreateXMLDocument()
{
XmlDocument xmlDoc = new XmlDocument();
//加入XML的声明段落,<?xml version="1.0" encoding="gb2312"?>
XmlDeclaration xmlDeclar;
xmlDeclar = xmlDoc.CreateXmlDeclaration("1.0", "gb2312", null);
xmlDoc.AppendChild(xmlDeclar);
//加入Employees根元素
XmlElement xmlElement = xmlDoc.CreateElement("", "Employees", "");
xmlDoc.AppendChild(xmlElement);
//添加节点
XmlNode root = xmlDoc.SelectSingleNode("Employees");
XmlElement xe1 = xmlDoc.CreateElement("Node");
xe1.SetAttribute("Name", "薪薪代码");
xe1.SetAttribute("ISB", "2-3631-4");
//添加子节点
XmlElement xeSub1 = xmlDoc.CreateElement("title");
xeSub1.InnerText = "学习VS";
xe1.AppendChild(xeSub1);
XmlElement xeSub2 = xmlDoc.CreateElement("price");
xe1.AppendChild(xeSub2);
XmlElement xeSub3 = xmlDoc.CreateElement("weight");
xeSub3.InnerText = "20";
xeSub2.AppendChild(xeSub3);
root.AppendChild(xe1);
xmlDoc.Save("D:\\book.xml");//保存的路径
}
增加节点
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("D:\\book.xml");//找到xml文件
XmlNode root = xmlDoc.SelectSingleNode("Employees");//查找Employees节点
XmlElement xe1 = xmlDoc.CreateElement("Node2");//添加Node2节点
xe1.SetAttribute("Name", "张飞");
XmlElement xeSub1 = xmlDoc.CreateElement("title");//定义子节点
xeSub1.InnerText = "心情好";
xe1.AppendChild(xeSub1);//添加节点到Node2
root.AppendChild(xe1);//添加节点到Employees
xmlDoc.Save("D:\\book.xml");
修改节点
public void ModifyNode()
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("D:\\book.xml");
XmlNodeList nodeList = xmlDocument.SelectSingleNode("Employees").ChildNodes;//获取Employees节点的所有子节点
foreach (XmlNode xn in nodeList)//遍历
{
XmlElement xe = (XmlElement)xn;
if (xe.GetAttribute("Name") == "薪薪代码")
{
xe.SetAttribute("Name", "薪薪");//更改节点的属性
XmlNodeList xnl = xe.ChildNodes;//获取xe的所有子节点
foreach (XmlNode xn1 in xnl)
{
XmlElement xe2 = (XmlElement)xn1;//将节点xn1的属性转换为XmlElement
if (xe2.Name == "title")//找到节点名字为title的节点
{
xe2.InnerText = "今天天气不好";
}
if (xe2.Name == "price")
{
XmlNodeList xnl2 = xe2.ChildNodes;
foreach (XmlNode xn2 in xnl2)
{
if (xn2.Name == "weight")
{
xn2.InnerText = "88";
}
}
}
}
}
}
xmlDocument.Save("D:\\book2.xml");
}
删除节点
public void DeleteNode()
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load("D:\\book1.xml");
XmlNodeList xnl = xmlDocument.SelectSingleNode("Employees").ChildNodes;
foreach (XmlNode xn in xnl)
{
if (xn.Name == "Node")
{
XmlElement xe = (XmlElement)xn;//将xn的属性转换为XmlElement
xe.RemoveAttribute("ID");//移除xe的ID属性
XmlNodeList xnl2 = xe.ChildNodes;
for (int i = 0; i < xnl2.Count; i++)
{
XmlElement xe2 = (XmlElement)xnl2.Item(i);
if (xe2.Name == "title")
{
xe.RemoveChild(xe2);//删除节点title
}
}
}
}
xmlDocument.Save("D:\\book3.xml");
}
c#读取xml文件
public void Load(string path)
{
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(path);
XmlNodeList xnl = xmlDocument.SelectSingleNode(managerNode).ChildNodes;
foreach (XmlNode xn in xnl)
{
if (xn.Name == configuration_ServerAddress)
{
ServerAddress = xn.InnerText;
}
}
}
catch(Exception ex)
{ }
}
如何在C#的泛型中使用多个数据类型
使用多个泛型类型参数,并在定义泛型类或方法时将它们作为参数。例如,定义一个名为Pair的泛型类,其中包含两个不同的泛型类型参数:
public class Pair<T, U>
{
public T First { get; set; }
public U Second { get; set; }
public Pair(T first, U second)
{
First = first;
Second = second;
}
}
在实例化这个类时,需要指定两个类型参数:
Pair<int, string> pair = new Pair<int, string>(10, "hello");
Console.WriteLine(pair.First); // 输出 10
Console.WriteLine(pair.Second); // 输出 "hello"
这样就可以在一个泛型类中使用多个不同的数据类型了。
C#中的URL参数加解密:实例与指南
在Web开发中,经常需要在URL中传递参数。然而,有时候我们希望对这些参数进行加密,以增加安全性并防止恶意篡改。本文将介绍如何在C#中对URL参数进行加密和解密,并提供一个实例来说明其用法。
一、URL参数加密:
在C#中对URL参数进行加密可以使用加密算法,例如AES(高级加密标准)或RSA(非对称加密算法)。下面是一个示例,展示了如何使用AES算法对URL参数进行加密:
using System;
using System.Security.Cryptography;
using System.Text;
public class UrlEncryptor
{
private static readonly byte[] Key = Encoding.UTF8.GetBytes("YourEncryptionKey123");
private static readonly byte[] Iv = Encoding.UTF8.GetBytes("YourEncryptionIV456");
public static string Encrypt(string plainText)
{
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = Iv;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
byte[] encryptedBytes = null;
using (var msEncrypt = new System.IO.MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new System.IO.StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encryptedBytes = msEncrypt.ToArray();
}
}
return Convert.ToBase64String(encryptedBytes);
}
}
}
二、URL参数解密:
解密过程与加密过程相反。下面是一个示例,展示了如何使用AES算法对加密的URL参数进行解密:
csharp
复制
using System;
using System.Security.Cryptography;
using System.Text;
public class UrlDecryptor
{
private static readonly byte[] Key = Encoding.UTF8.GetBytes("YourEncryptionKey123");
private static readonly byte[] Iv = Encoding.UTF8.GetBytes("YourEncryptionIV456");
public static string Decrypt(string cipherText)
{
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = Iv;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (var msDecrypt = new System.IO.MemoryStream(cipherBytes))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new System.IO.StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
}
}
}
三、实例:
现在我们可以使用上述的加密和解密方法对URL参数进行处理。下面是一个示例:
public class Program
{
public static void Main(string[] args)
{
string originalUrlParam = "Hello World";
// 加密URL参数
string encryptedUrlParam = UrlEncryptor.Encrypt(originalUrlParam);
Console.WriteLine("加密后的URL参数:" + encryptedUrlParam);
// 解密URL参数
string decryptedUrlParam = UrlDecryptor.Decrypt(encryptedUrlParam);
Console.WriteLine("解密后的URL参数:" + decryptedUrlParam);
}
}
以上示例演示了如何使用AES算法对URL参数进行加密和解密。你可以根据自己的需求选择其他加密算法,并根据实际情况对密钥和初始化向量进行更安全的管理。
结论:
在C#中对URL参数进行加密和解密可以提高传输安全性,并防止恶意篡改。通过使用适当的加密算法和正确管理密钥,可以确保数据的机密性和完整性。希望本文对你理解URL参数加解密在C#中的实现有所帮助!
WebView2的三个版本
WebView2 是 Microsoft Edge 浏览器的一个组件,它允许开发人员在其本机应用程序中嵌入 Web 技术。以下是
三种不同的 WebView2 分发方式及其区别:
常青引导程序(Evergreen Bootstrapper):
常青引导程序是一个小型的安装程序,用于检测系统上是否已安装 WebView2 运行时。
如果系统上尚未安装 WebView2 运行时,引导程序将自动下载并安装最新版本的 WebView2 运行时。
引导程序确保应用程序始终使用最新版本的 WebView2 运行时,无需手动更新。
适用于希望自动更新 WebView2 运行时且不需要特定版本控制的应用程序。
常青独立安装程序(Evergreen Standalone Installer):
常青独立安装程序是一个完整的安装程序,其中包含 WebView2 运行时。
安装程序将 WebView2 运行时直接安装到应用程序的目录中,而不依赖于系统范围内的安装。
每次运行安装程序时,都会安装最新版本的 WebView2 运行时。
适用于希望将 WebView2 运行时与应用程序捆绑在一起,并在每次安装时获取最新版本的情况。
固定版本(Fixed Version):
固定版本是指将特定版本的 WebView2 运行时与应用程序捆绑在一起。
开发人员可以选择特定版本的 WebView2 运行时,并将其包含在应用程序的安装包中。
应用程序将始终使用捆绑的 WebView2 运行时版本,而不会自动更新。
适用于需要对 WebView2 运行时进行版本控制,或者希望确保应用程序在不同环境中使用相同版本的 WebView2 运行时的情况。
选择适合的 WebView2 分发方式取决于应用程序的需求和部署策略。常青引导程序提供自动更新功能,而常青独立安装程序则将 WebView2 运行时与应用程序捆绑在一起。固定版本允许对 WebView2 运行时进行精确的版本控制。开发人员可以根据应用程序的更新频率、版本稳定性要求以及部署环境来选择合适的方式。
在 C# 代码中使用这三个版本的 WebView2 时,主要区别在于初始化 WebView2 环境的方式。以下是针对每个版本的示例代码:
常青引导程序(Evergreen Bootstrapper):
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
public async void InitializeWebView()
{
var webView2Environment = await CoreWebView2Environment.CreateAsync(null, null, new CoreWebView2EnvironmentOptions("--disable-web-security"));
await webView.EnsureCoreWebView2Async(webView2Environment);
}
常青独立安装程序(Evergreen Standalone Installer):
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
public async void InitializeWebView()
{
var webView2Environment = await CoreWebView2Environment.CreateAsync(null, "path/to/standalone/installer", new CoreWebView2EnvironmentOptions("--disable-web-security"));
await webView.EnsureCoreWebView2Async(webView2Environment);
}
固定版本(Fixed Version):
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.Wpf;
public async void InitializeWebView()
{
var webView2Environment = await CoreWebView2Environment.CreateAsync("path/to/fixed/version", null, new CoreWebView2EnvironmentOptions("--disable-web-security"));
await webView.EnsureCoreWebView2Async(webView2Environment);
}
区别在于 CreateAsync 方法的参数:
常青引导程序:
第一个参数设置为 null,表示使用默认的 WebView2 运行时。
第二个参数设置为 null,表示使用默认的用户数据文件夹。
常青独立安装程序:
第一个参数设置为 null,表示使用默认的 WebView2 运行时。
第二个参数设置为独立安装程序的路径,指定 WebView2 运行时的位置。
固定版本:
第一个参数设置为固定版本的 WebView2 运行时的路径。
第二个参数设置为 null,表示使用默认的用户数据文件夹。
请注意,以上示例代码假设你使用的是 WPF 框架,并且已经正确设置了 WebView2 的引用和命名空间。
在所有情况下,都需要先创建一个 CoreWebView2Environment 对象,然后将其传递给 WebView2 控件的 EnsureCoreWebView2Async 方法以确保 WebView2 环境已正确初始化。
选择适合你的应用程序需求的版本,并相应地调整代码。
C#使用Edge
nuget使用“Microsoft.Web.WebView2”
Install-Package Microsoft.Web.WebView2
点击下载运行时:
MicrosoftEdgeWebview2Setup.rar
WebView2依附的进程是msedge.exe或msedgewebview2.exe
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
class Program
{
static async Task Main(string[] args)
{
string url = "https://www.example.com"; // 指定要打开的URL
// 创建一个窗口来托管WebView2控件
Form form = new Form();
form.Width = 800;
form.Height = 600;
// 创建WebView2控件
WebView2 webView = new WebView2();
webView.Dock = DockStyle.Fill;
form.Controls.Add(webView);
// 初始化WebView2控件
await webView.EnsureCoreWebView2Async();
// 导航到指定URL
webView.CoreWebView2.Navigate(url);
// 等待导航完成
await webView.CoreWebView2.NavigationCompleted;
// 获取浏览器内指定URL的Cookie值
var cookies = await webView.CoreWebView2.CookieManager.GetCookiesAsync(url);
foreach (var cookie in cookies)
{
Console.WriteLine($"Cookie Name: {cookie.Name}, Value: {cookie.Value}");
}
// 关闭窗口
form.Close();
}
}
有关固定版本运行时分发模式的详细信息
对于具有严格兼容性要求的受限环境,请考虑使用固定版本分发模式。 固定版本分发模式以前称为 “自带”。
在“固定版本”分发模式下,可以控制应用的 WebView2 运行时的更新时间。 下载特定版本的 WebView2 运行时,然后将其与 WebView2 应用一起打包。 客户端上的 WebView2 运行时不会自动更新。 相反,会定期更新打包和分发的 WebView2 运行时以及更新的应用。 固定版本方法不使用 WebView2 运行时的注册表项。
固定版本二进制文件超过 250 MB,将使应用包更大。
若要使用固定版本分发模式,请执行以下操作:
1.从下载 WebView2 运行时中下载 固定版本的 WebView2 运行时,作为包。
此站点上提供了最新和第二个最新主要版本的修补次数最多的版本。 保留所需任何版本的存档副本。
2.使用命令行命令 expand {path to the package} -F:* {path to the destination folder} 或使用 WinRAR 等解压缩工具解压缩 WebView2 运行时包。 避免通过文件资源管理器解压缩,因为该方法可能不会生成正确的文件夹结构。
3.在应用包中包含所有解压缩的固定版本二进制文件,在应用安装期间将部署在目标计算机上。
4.指示创建 WebView2 环境时固定版本二进制文件的路径。
对于 Win32 C/C++,可以使用 CreateCoreWebView2EnvironmentWithOptions 函数创建环境。 browserExecutableFolder使用 参数指示包含 msedgewebview2.exe的文件夹的路径。
对于 .NET,必须在 WebView2 Source 属性生效之前指定环境。 对于 .NET,可以使用以下任一方法来指定环境:
在 CreationProperties 元素上WebView2设置 (WPF/WinForms) 属性。 BrowserExecutableFolder使用 (WPF/WinForms) 类中的 CoreWebView2CreationProperties 成员来指示固定版本二进制文件的路径。
或者,使用 EnsureCoreWebView2Async (WPF/WinForms) 指定环境。 browserExecutableFolder使用 CoreWebView2Environment.CreateAsync 中的 参数来指示固定版本二进制文件的路径。
对于 WinUI,通过指定安装位置并设置运行时路径的环境变量,确保应用有权访问文件夹。 执行此操作的一种方法是将以下 C# 代码添加到应用:
StorageFolder localFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
String fixedPath = Path.Combine(localFolder.Path, "FixedRuntime\\(version number)");
Debug.WriteLine($"Launch path [{localFolder.Path}]");
Debug.WriteLine($"FixedRuntime path [{fixedPath}]");
Environment.SetEnvironmentVariable("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", fixedPath);
5.随应用打包并交付固定版本二进制文件。 根据需要更新二进制文件。
对于 WinUI,这可能包括在代码编辑器中打开项目文件 (.csproj) ,然后在项目标记中添加以下代码:
<ItemGroup>
<Content Include="FixedRuntime\(version number)\\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
验证文件夹是否具有匹配的 bin\**designated architecture**\Release FixedRuntime\ (版本号) 文件夹中的运行时文件。
6.在Windows 10设备上,从固定版本 120 开始,使用固定版本的未打包 Win32 应用程序的开发人员必须运行以下命令,以便“固定版本”继续工作。 这是由于 v120 中在应用容器中运行呈现器进程的安全性改进。 此更改不会影响Windows 11设备、旧运行时或打包的应用。
找到在用户设备上部署固定版本包的路径,例如以下位置:
D:\myapp\Microsoft.WebView2.FixedVersionRuntime.87.0.664.8.x64
在用户的设备上运行以下命令:
icacls {Fixed Version path} /grant *S-1-15-2-2:(OI)(CI)(RX)
icacls {Fixed Version path} /grant *S-1-15-2-1:(OI)(CI)(RX)
确认在“固定版本”文件夹的“安全性”选项卡中为 ALL APPLICATION PACKAGES 和 ALL RESTRICTED APPLICATION PACKAGES 授予了权限,如下所示:
WebView2 优势
Web 生态系统和技能集。 利用 web 生态系统中存在的整个 web 平台、库、工具以及人才。
快速创新。 Web 开发允许快速部署和迭代。
Windows 10和 11 支持。 支持跨Windows 10和Windows 11提供一致的用户体验。
本机功能。 访问完整的本机 API 集。
代码共享。 向代码库添加 web 代码可以增加跨多个平台的重用。
Microsoft 支持。 Microsoft 在受支持的平台上提供支持并添加新功能请求。
常青分布。 依赖带有定期平台更新和安全修补的最新版 Chromium。
已修复版本分布。 也可以在应用中打包特定版本的 Chromium 位。
增量采用。 逐步将 web 组件添加到应用。
受支持的平台
支持以下编程环境:
Win32 C/C++
.NET Framework 4.5 或更高版本
.NET Core 3.1 或更高版本
.NET 5 或更高版本
WinUI 2.0
WinUI 3.0
WebView2 应用可以在以下版本的 Windows 上运行:
Windows 11
Windows 10
Windows 10 IoT 企业版 LTSC x32 2019
Windows 10 IoT 企业版 LTSC x64 2019
Windows 10 IoT 企业版 21h1 x64
Windows Server 2022
Windows Server 2019
Windows Server 2016
以下设备还支持 WebView2:
Xbox
HoloLens 2
Windows 7 和 8
WebView2 运行时版本 109 是支持以下 Windows 版本的最终版本。 WebView2 运行时和 SDK 版本 110.0.1519.0 及更高版本不支持这些操作系统。
Windows 8/8.1
Windows 7
Windows Server 2012 R2
Windows Server 2012
Windows Server 2008 R2
private void Form1_Load(object sender, EventArgs e)
{
webView21.Source = new Uri("https://core.quickso.cn/");
}
private void button2_Click(object sender, EventArgs e)
{
if(webView21!=null && webView21.CoreWebView2!=null)
webView21.CoreWebView2.Navigate("https://baidu.com/");
}
private void webView21_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
MessageBox.Show("加载完毕");
// 检查页面是否加载成功
if (e.IsSuccess)
{
// 页面加载完毕
// 在这里执行你的代码逻辑
}
else
{
// 页面加载失败
// 在这里处理加载失败的逻辑
}
}
获得cookie串
async private void button2_Click(object sender, EventArgs e)
{
if (webView21 != null && webView21.CoreWebView2 != null)
{
string targetUrl = webView21.CoreWebView2.Source.ToString();
List<CoreWebView2Cookie> cookies = await webView21.CoreWebView2.CookieManager.GetCookiesAsync(targetUrl);
//string cookieString = string.Join("; ", coreWebView2CookieList.Select(cookie => $"{cookie.Name}={cookie.Value}"));
string allString = "";
foreach (var cookie in cookies)
{
if(allString!="")
{
allString += ";";
}
allString += cookie.Name + "=" + cookie.Value;
// 输出每个 cookie 的详细信息
/*
Console.WriteLine($"Name: {cookie.Name}");
Console.WriteLine($"Value: {cookie.Value}");
Console.WriteLine($"Domain: {cookie.Domain}");
Console.WriteLine($"Path: {cookie.Path}");
Console.WriteLine($"HttpOnly: {cookie.HttpOnly}");
Console.WriteLine($"Secure: {cookie.Secure}");
Console.WriteLine($"Expires: {cookie.Expires?.ToLocalTime() ?? "Not set"}");
Console.WriteLine("--------------------");
*/
}
Clipboard.SetText(allString);
//MessageBox.Show(allString);
}
}
Webview2是由Microsoft提供的一个基于Chromium的新版Webview控件,支持Windows 10以上操作系统。它可以在Windows应用程序中嵌入Web页面,并支持与Web页面进行通讯。以下是使用Webview2实现C#与JS通讯的步骤:
1. 安装Webview2运行时
Webview2需要安装运行时才能在应用程序中使用。运行时可以通过NuGet包管理器安装,也可以从Microsoft官网下载安装程序手动安装。安装完成后,需要在项目中添加对Microsoft.Web.WebView2.WinForms或Microsoft.Web.WebView2.WinForms.Design的引用。
2. 初始化Webview2控件
在Windows应用程序中创建一个Webview2控件,并初始化它。初始化的代码如下:
private async void Form1_Load(object sender, EventArgs e)
{
await webView21.EnsureCoreWebView2Async();
webView21.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
}
其中,webView21 是 Webview2 控件。 EnsureCoreWebView2Async() 会异步地初始化Webview2控件,并返回一个CoreWebView2实例。CoreWebView2_WebMessageReceived 是一个 Webview2 控件的事件,它在Webview2控件接收到JS消息时被触发。
3. 发送消息到JS
在C#代码中,可以通过CoreWebView2实例的 PostWebMessageAsJson 或 PostWebMessageAsJsonAsync 方法向JS发送消息。消息必须是一个JSON对象。例如,向JS发送一个字符串类型的消息可以这样写:
private void button1_Click(object sender, EventArgs e)
{
string msg = "Hello from C#";
webView21.CoreWebView2.PostWebMessageAsJson(msg);
}
4. 接收JS消息
在JS脚本中,可以通过 window.chrome.webview.postMessage 方法向C#发送消息。消息也必须是一个JSON对象。例如,向C#发送一个数字类型的消息可以这样写:
window.chrome.webview.postMessage(123);
在C#代码中,当Webview2控件接收到JS消息时,CoreWebView2_WebMessageReceived 事件会被触发。可以在该事件处理程序中解析接收到的消息,然后响应对应的业务逻辑。例如:
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
try
{
int msg = int.Parse(e.TryGetWebMessageAsString());
MessageBox.Show($"Got message from JS: {msg}");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
以上就是使用Webview2实现C#与JS通讯的步骤。通过这种方式,我们可以在Windows应用程序中方便地集成Web页面,并与Web页面进行双向通讯。
执行JS代码
// 执行JavaScript代码的方法
private async void ExecuteJavaScript(string javascript)
{
if (webView2Control.CoreWebView2 != null)
{
try
{
// 异步执行JavaScript代码
await webView2Control.CoreWebView2.ExecuteScriptAsync(javascript);
}
catch (Exception ex)
{
// 处理可能发生的任何异常
Console.WriteLine(ex.Message);
}
}
}
// 假设你想在某个事件中执行JavaScript代码,如按钮点击事件
private void ButtonExecuteJS_Click(object sender, EventArgs e)
{
string javascript = "alert('Hello from JavaScript!');";
ExecuteJavaScript(javascript);
}
如何 等webView2 加载完成网页,进行下一下
在使用WebView2加载网页时,可以通过使用LoadCompleted事件来检测网页是否已经完成加载,然后执行下一步操作。下面是示例代码:
private void WebView2_LoadCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
// 网页加载完成后执行下一步操作
// 下一步操作
}
在上面的代码中,我们使用了CoreWebView2NavigationCompletedEventArgs对象来检测网页是否已经完成加载。当网页加载完成时,LoadCompleted事件将被触发,并且可以继续执行下一步操作。
还可以通过调用WebView2对象的ExecuteScriptAsync方法来执行JavaScript代码,以便在网页加载完成后执行一些自定义操作,例如:
private async void WebView2_LoadCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
{
// 网页加载完成后执行下一步操作
await WebView2.ExecuteScriptAsync("alert('网页加载完成')");
// 下一步操作
}
在上述示例中,我们使用了ExecuteScriptAsync方法来执行一个JavaScript弹出窗口,以便在网页加载完成后通知用户。然后,我们可以在下一步操作中进行任何其他需要执行的操作。
还有使用Microsoft.Toolkit.Forms.UI.Controls.WebView
nuget安装包Microsoft.Toolkit.Forms.UI.Controls.WebView
将Microsoft.Toolkit.Forms.UI.Controls.WebView.dll拖到工具箱,然后点击WebView拖到界面
private Microsoft.Toolkit.Forms.UI.Controls.WebView webView1;
这个WebView有个大小Bug需要在Form_Load里修正一下
private void Form1_Load(object sender, EventArgs e)
{
int w = webView1.Width;
int h = webView1.Height;
webView1.Height = h + 1;
webView1.Height = h;
}
C#WebSocketServer
WebSocketServer是C#中用于创建WebSocket服务器的类库。WebSocket是一种在单个TCP连接上进行全双工通信的协议,它允许服务器主动向客户端推送数据,非常适合需要实时交互的应用,如聊天室、协作编辑、多人游戏等。
使用WebSocketServer创建WebSocket服务器的一般步骤如下:
添加WebSocketServer的NuGet包
首先需要通过NuGet包管理器,搜索并安装WebSocketServer包。在Visual Studio的解决方案资源管理器中右击项目,选择"管理NuGet程序包",搜索WebSocketServer并安装。
创建WebSocket服务器实例
安装完成后,在代码中创建WebSocketServer实例,指定监听的IP地址和端口号。例如:
var server = new WebSocketServer("ws://localhost:8080");
注册WebSocket事件处理
WebSocketServer提供了一些事件用于处理连接、接收消息等,需要为这些事件注册相应的处理程序。主要事件包括:
NewSessionConnected: 新的WebSocket会话连接时触发
SessionClosed: WebSocket会话关闭时触发
NewMessageReceived: 收到新消息时触发
例如,注册一个NewMessageReceived事件处理程序:
server.NewMessageReceived += NewMessage;
private void NewMessage(object sender, MessageReceivedEventArgs e)
{
Console.WriteLine($"收到新消息: {e.Message}");
e.Session.SendAsync($"服务器收到消息: {e.Message}");
}
启动WebSocket服务器
注册完事件后,调用Start方法启动WebSocket服务器,开始监听客户端连接请求。
server.Start();
Console.WriteLine($"WebSocket服务器已启动,监听 ws://localhost:8080");
客户端连接WebSocket服务器
服务端启动后,客户端就可以通过WebSocket连接服务器了。客户端可以是网页中的JavaScript、iOS/Android移动应用、桌面程序等。以网页JavaScript为例:
var ws = new WebSocket("ws://localhost:8080");
ws.onopen = function() {
console.log("连接已建立");
ws.send("你好,WebSocket服务器!");
};
ws.onmessage = function(evt) {
console.log("收到服务器消息: " + evt.data);
};
以上就是C# WebSocketServer的基本使用流程。WebSocketServer还提供了一些其他特性,如自定义WebSocket子协议、会话管理、异常处理等。你可以根据实际需求使用这些功能。
WebSocket是一种非常强大和灵活的实时通信技术,借助C# WebSocketServer可以方便地创建出高性能的实时应用。但WebSocket协议相对比较低层,开发时需要处理连接管理、心跳检测、消息编解码等细节。对于更高层的实时应用协议,如Socket.IO、SignalR等,有更完善的C#框架可供选择。
C# ProxyServer
C# ProxyServer是一个基于.NET框架的代理服务器库,可以用于创建自定义的代理服务器应用程序。它支持HTTP、HTTPS、SOCKS4和SOCKS5等多种代理协议,并提供了灵活的API接口用于处理客户端请求和服务器响应。
主要特性:
支持HTTP、HTTPS、SOCKS4、SOCKS5等多种代理协议
支持透明代理和显式代理模式
支持用户身份验证
支持SSL/TLS加密
支持自定义请求和响应处理
跨平台支持(Windows、Linux、macOS)
使用方法:
安装NuGet包
Install-Package ProxyServer
创建代理服务器实例
var proxyServer = new ProxyServer();
配置代理服务器选项
proxyServer.BeforeRequest += OnBeforeRequest;
proxyServer.BeforeResponse += OnBeforeResponse;
proxyServer.ServerCertificateValidationCallback += OnCertificateValidation;
proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection;
启动代理服务器
var proxyEndPoint = new IPEndPoint(IPAddress.Any, 8080);
proxyServer.Start(proxyEndPoint);
处理请求和响应
private async Task OnBeforeRequest(object sender, SessionEventArgs e)
{
// 处理客户端请求
var request = e.HttpClient.Request;
if (request.Host == "example.com" && request.RequestUri.AbsolutePath == "/api/data")
{
e.Ok("<!DOCTYPE html><html><body><h1>Blocked</h1></body></html>",
HttpStatusCode.Forbidden);
}
}
private async Task OnBeforeResponse(object sender, SessionEventArgs e)
{
// 处理服务器响应
var response = e.HttpClient.Response;
if (response.StatusCode == HttpStatusCode.OK)
{
if (response.ContentType != null && response.ContentType.Trim().ToLower().Contains("text/html"))
{
var body = await response.Content.ReadAsStringAsync();
await response.Content.LoadIntoBufferAsync();
response.Content = new StringContent(body.Replace("Example", "Test"),
Encoding.UTF8, response.ContentType);
}
}
}
停止代理服务器
proxyServer.Stop();
以上是C# ProxyServer库的基本使用方法。通过创建ProxyServer实例,配置各种选项和回调函数,然后启动服务器并处理请求和响应,就可以实现一个功能强大的代理服务器应用程序。在处理请求和响应时,可以对数据进行拦截、修改、过滤等操作,以满足不同的需求。
该库还支持更多高级功能,如并发处理、速率限制、缓存等,可以根据实际需要进行配置和使用。同时,由于它是跨平台的,可以在Windows、Linux、macOS等多个操作系统上运行,非常方便。
C#通过IPV6通讯的服务端与客户端的例子
一个使用实际IPv6地址的例子:
服务端代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Server
{
static void Main(string[] args)
{
IPAddress ipAddress = IPAddress.Parse("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); // 实际的IPv6地址
int port = 8888;
TcpListener listener = new TcpListener(ipAddress, port);
listener.Start();
Console.WriteLine("Server started. Waiting for connections...");
while (true)
{
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Client connected: " + client.Client.RemoteEndPoint);
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received message: " + message);
string response = "Hello from server!";
byte[] responseBytes = Encoding.ASCII.GetBytes(response);
stream.Write(responseBytes, 0, responseBytes.Length);
client.Close();
}
}
}
客户端代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class Client
{
static void Main(string[] args)
{
IPAddress ipAddress = IPAddress.Parse("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); // 实际的IPv6地址
int port = 8888;
TcpClient client = new TcpClient();
client.Connect(ipAddress, port);
Console.WriteLine("Connected to server: " + client.Client.RemoteEndPoint);
NetworkStream stream = client.GetStream();
string message = "Hello from client!";
byte[] messageBytes = Encoding.ASCII.GetBytes(message);
stream.Write(messageBytes, 0, messageBytes.Length);
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
string response = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received response: " + response);
client.Close();
}
}
在这个例子中,服务端和客户端都使用了一个实际的IPv6地址 2001:0db8:85a3:0000:0000:8a2e:0370:7334。这个地址只是一个例子,你需要替换成你实际使用的IPv6地址。
服务端在指定的IPv6地址和端口上监听连接,当有客户端连接时,接受连接,读取客户端发送的消息,并向客户端发送一个响应消息。
客户端使用相同的IPv6地址和端口连接到服务端,发送一个消息,并接收服务端的响应消息。
要运行这个例子,你需要确保服务端和客户端都能访问到指定的IPv6地址。服务端需要首先启动,然后客户端才能连接到服务端。
请注意,这个例子假设服务端和客户端在同一个网络中。如果它们在不同的网络中,你可能需要配置网络设置和防火墙规则以允许通信。
上一篇:C#经验总结