温州网站建设哪里好河南网站建设的详细策划

web/2025/9/26 4:06:47/文章来源:
温州网站建设哪里好,河南网站建设的详细策划,中国建设银行校园招聘网站,关键词指数查询工具源码下载#xff1a;http://www.tracefact.net/SourceCode/Network-Part3.rar C#网络编程(异步传输字符串) - Part.3 这篇文章我们将前进一大步#xff0c;使用异步的方式来对服务端编程#xff0c;以使它成为一个真正意义上的服务器#xff1a;可以为多个客户端的多次请求…  源码下载http://www.tracefact.net/SourceCode/Network-Part3.rar C#网络编程(异步传输字符串) - Part.3 这篇文章我们将前进一大步使用异步的方式来对服务端编程以使它成为一个真正意义上的服务器可以为多个客户端的多次请求服务。但是开始之前我们需要解决上一节中遗留的一个问题。 消息发送时的问题 这个问题就是客户端分两次向流中写入数据比如字符串时我们主观上将这两次写入视为两次请求然而服务端有可能将这两次合起来视为一条请求这在两个请求间隔时间比较短的情况下尤其如此。同样也有可能客户端发出一条请求但是服务端将其视为两条请求处理。下面列出了可能的情况假设我们在客户端连续发送两条“Welcome to Tracefact.net!”则数据到达服务端时可能有这样三种情况 NOTE在这里我们假设采用ASCII编码方式因为此时上面的一个方框正好代表一个字节而字符串到达末尾后为持续的0因为byte是值类型且最小为0。 上面的第一种情况是最理想的情况此时两条消息被视为两个独立请求由服务端完整地接收。第二种情况的示意图如下此时一条消息被当作两条消息接收了 而对于第三种情况则是两条消息被合并成了一条接收 如果你下载了上一篇文章所附带的源码那么将Client2.cs进行一下修改不通过用户输入而是使用一个for循环连续的发送三个请求过去这样会使请求的间隔时间更短下面是关键代码 string msg Welcome to TraceFact.Net!;for (int i 0; i 2; i) {    byte[] buffer Encoding.Unicode.GetBytes(msg);     // 获得缓存    try {        streamToServer.Write(buffer, 0, buffer.Length); // 发往服务器        Console.WriteLine(Sent: {0}, msg);    } catch (Exception ex) {        Console.WriteLine(ex.Message);        break;    }} 运行服务端然后再运行这个客户端你可能会看到这样的结果 可以看到尽管上面将消息分成了三条单独发送但是服务端却将后两条合并成了一条。对于这些情况我们可以这样处理就好像HTTP协议一样在实际的请求和应答内容之前包含了HTTP头其中是一些与请求相关的信息。我们也可以订立自己的协议来解决这个问题比如说对于上面的情况我们就可以定义这样一个协议 [lengthXXX]其中xxx是实际发送的字符串长度注意不是字节数组buffer的长度那么对于上面的请求则我们发送的数据为“[length25]Welcome to TraceFact.Net!”。而服务端接收字符串之后首先读取这个“元数据”的内容然后再根据“元数据”内容来读取实际的数据它可能有下面这样两种情况 NOTE我觉得这里借用“元数据”这个术语还算比较恰当因为“元数据”就是用来描述数据的数据。 “[“”]”中括号是完整的可以读取到length的字节数。然后根据这个数值与后面的字符串长度相比如果相等则说明发来了一条完整信息如果多了那么说明接收的字节数多了取出合适的长度并将剩余的进行缓存如果少了说明接收的不够那么将收到的进行一个缓存等待下次请求然后将两条合并。“[”“]”中括号本身就不完整此时读不到length的值因为中括号里的内容被截断了那么将读到的数据进行缓存等待读取下次发送来的数据然后将两次合并之后再按上面的方式进行处理。 接下来我们来看下如何来进行实际的操作实际上这个问题已经不属于C#网络编程的内容了而完全是对字符串的处理。所以我们不再编写服务端/客户端代码直接编写处理这几种情况的方法 public class RequestHandler {    private string temp string.Empty;    public string[] GetActualString(string input) {        return GetActualString(input, null);    }    private string[] GetActualString(string input, Liststring outputList) {        if (outputList null)            outputList new Liststring();        if (!String.IsNullOrEmpty(temp))            input temp input;        string output ;        string pattern (?^\[length)(\d)(?\]);        int length;                            if (Regex.IsMatch(input, pattern)) {            Match m Regex.Match(input, pattern);            // 获取消息字符串实际应有的长度            length Convert.ToInt32(m.Groups[0].Value);            // 获取需要进行截取的位置            int startIndex input.IndexOf(]) 1;            // 获取从此位置开始后所有字符的长度            output input.Substring(startIndex);            if (output.Length length) {                // 如果output的长度与消息字符串的应有长度相等                // 说明刚好是完整的一条信息                outputList.Add(output);                temp ;            } else if (output.Length length) {                // 如果之后的长度小于应有的长度                // 说明没有发完整则应将整条信息包括元数据全部缓存                // 与下一条数据合并起来再进行处理                temp input;                // 此时程序应该退出因为需要等待下一条数据到来才能继续处理            } else if (output.Length length) {                // 如果之后的长度大于应有的长度                // 说明消息发完整了但是有多余的数据                // 多余的数据可能是截断消息也可能是多条完整消息                // 截取字符串                output output.Substring(0, length);                outputList.Add(output);                temp ;                // 缩短input的长度                input input.Substring(startIndex length);                // 递归调用                GetActualString(input, outputList);            }        } else {    // 说明“[”“]”就不完整            temp input;        }        return outputList.ToArray();    }} 这个方法接收一个满足协议格式要求的输入字符串然后返回一个数组这是因为如果出现多次请求合并成一个发送过来的情况那么就将它们全部返回。随后简单起见我在这个类中添加了一个静态的Test()方法和PrintOutput()帮助方法进行了一个简单的测试注意我直接输入了length13这个是我提前计算好的。 public static void Test() {    RequestHandler handler new RequestHandler();    string input;    // 第一种情况测试 - 一条消息完整发送    input [length13]明天中秋祝大家节日快乐;    handler.PrintOutput(input);    // 第二种情况测试 - 两条完整消息一次发送    input 明天中秋祝大家节日快乐;    input String.Format        ([length13]{0}[length13]{0}, input);    handler.PrintOutput(input);    // 第三种情况测试A - 两条消息不完整发送    input [length13]明天中秋祝大家节日快乐[length13]明天中秋;    handler.PrintOutput(input);    input 祝大家节日快乐;    handler.PrintOutput(input);    // 第三种情况测试B - 两条消息不完整发送    input [length13]明天中秋祝大家;    handler.PrintOutput(input);    input 节日快乐[length13]明天中秋祝大家节日快乐;    handler.PrintOutput(input);        // 第四种情况测试 - 元数据不完整    input [leng;    handler.PrintOutput(input);     // 不会有输出    input th13]明天中秋祝大家节日快乐;    handler.PrintOutput(input);}// 用于测试输出private void PrintOutput(string input) {    Console.WriteLine(input);    string[] outputArray GetActualString(input);    foreach (string output in outputArray) {        Console.WriteLine(output);    }    Console.WriteLine();} 运行上面的程序可以得到如下的输出 OK从上面的输出可以看到这个方法能够满足我们的要求。对于这篇文章最开始提出的问题可以很轻松地通过加入这个方法来解决这里就不再演示了但在本文所附带的源代码含有修改过的程序。在这里花费了很长的时间接下来让我们回到正题看下如何使用异步方式完成上一篇中的程序吧。 异步传输字符串 在上一篇中我们由简到繁提到了服务端的四种方式服务一个客户端的一个请求、服务一个客户端的多个请求、服务多个客户端的一个请求、服务多个客户端的多个请求。我们说到可以将里层的while循环交给一个新建的线程去让它来完成。除了这种方式以外我们还可以使用一种更好的方式――使用线程池中的线程来完成。我们可以使用BeginRead()、BeginWrite()等异步方法同时让这BeginRead()方法和它的回调方法形成一个类似于while的无限循环首先在第一层循环中接收到一个客户端后调用BeginRead()然后为该方法提供一个读取完成后的回调方法然后在回调方法中对收到的字符进行处理随后在回调方法中接着调用BeginRead()方法并传入回调方法本身。 由于程序实现功能和上一篇完全相同我就不再细述了。而关于异步调用方法更多详细内容可以参见 C#中的委托和事件(续)。 1.服务端的实现 当程序越来越复杂的时候就需要越来越高的抽象所以从现在起我们不再把所有的代码全部都扔进Main()里这次我创建了一个RemoteClient类它对于服务端获取到的TcpClient进行了一个包装 public class RemoteClient {    private TcpClient client;    private NetworkStream streamToClient;    private const int BufferSize 8192;    private byte[] buffer;    private RequestHandler handler;        public RemoteClient(TcpClient client) {        this.client client;        // 打印连接到的客户端信息        Console.WriteLine(\nClient Connected{0} -- {1},            client.Client.LocalEndPoint, client.Client.RemoteEndPoint);        // 获得流        streamToClient client.GetStream();        buffer new byte[BufferSize];        // 设置RequestHandler        handler new RequestHandler();        // 在构造函数中就开始准备读取        AsyncCallback callBack new AsyncCallback(ReadComplete);        streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);    }    // 再读取完成时进行回调    private void ReadComplete(IAsyncResult ar) {        int bytesRead 0;        try {            lock (streamToClient) {                bytesRead streamToClient.EndRead(ar);                Console.WriteLine(Reading data, {0} bytes ..., bytesRead);            }            if (bytesRead 0) throw new Exception(读取到0字节);            string msg Encoding.Unicode.GetString(buffer, 0, bytesRead);            Array.Clear(buffer,0,buffer.Length);        // 清空缓存避免脏读                    string[] msgArray handler.GetActualString(msg);   // 获取实际的字符串            // 遍历获得到的字符串            foreach (string m in msgArray) {                Console.WriteLine(Received: {0}, m);                string back m.ToUpper();                // 将得到的字符串改为大写并重新发送                byte[] temp Encoding.Unicode.GetBytes(back);                streamToClient.Write(temp, 0, temp.Length);                streamToClient.Flush();                Console.WriteLine(Sent: {0}, back);            }                           // 再次调用BeginRead()完成时调用自身形成无限循环            lock (streamToClient) {                AsyncCallback callBack new AsyncCallback(ReadComplete);                streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);            }        } catch(Exception ex) {            if(streamToClient!null)                streamToClient.Dispose();            client.Close();            Console.WriteLine(ex.Message);      // 捕获异常时退出程序                      }    }} 随后我们在主程序中仅仅创建TcpListener类型实例由于RemoteClient类在构造函数中已经完成了初始化的工作所以我们在下面的while循环中我们甚至不需要调用任何方法 class Server {    static void Main(string[] args) {        Console.WriteLine(Server is running ... );        IPAddress ip new IPAddress(new byte[] { 127, 0, 0, 1 });        TcpListener listener new TcpListener(ip, 8500);        listener.Start();           // 开始侦听        Console.WriteLine(Start Listening ...);        while (true) {            // 获取一个连接同步方法在此处中断            TcpClient client listener.AcceptTcpClient();                          RemoteClient wapper new RemoteClient(client);        }    }} 好了服务端的实现现在就完成了接下来我们再看一下客户端的实现 2.客户端的实现 与服务端类似我们首先对TcpClient进行一个简单的包装使它的使用更加方便一些因为它是服务端的客户所以我们将类的名称命名为ServerClient public class ServerClient {    private const int BufferSize 8192;    private byte[] buffer;    private TcpClient client;    private NetworkStream streamToServer;    private string msg Welcome to TraceFact.Net!;    public ServerClient() {        try {            client new TcpClient();            client.Connect(localhost, 8500);      // 与服务器连接        } catch (Exception ex) {            Console.WriteLine(ex.Message);            return;        }        buffer new byte[BufferSize];        // 打印连接到的服务端信息        Console.WriteLine(Server Connected{0} -- {1},            client.Client.LocalEndPoint, client.Client.RemoteEndPoint);        streamToServer client.GetStream();    }    // 连续发送三条消息到服务端    public void SendMessage(string msg) {        msg String.Format([length{0}]{1}, msg.Length, msg);        for (int i 0; i 2; i) {            byte[] temp Encoding.Unicode.GetBytes(msg);   // 获得缓存            try {                streamToServer.Write(temp, 0, temp.Length); // 发往服务器                Console.WriteLine(Sent: {0}, msg);            } catch (Exception ex) {                Console.WriteLine(ex.Message);                break;            }        }        lock (streamToServer) {            AsyncCallback callBack new AsyncCallback(ReadComplete);            streamToServer.BeginRead(buffer, 0, BufferSize, callBack, null);        }    }    public void SendMessage() {        SendMessage(this.msg);    }    // 读取完成时的回调方法    private void ReadComplete(IAsyncResult ar) {        int bytesRead;        try {            lock (streamToServer) {                bytesRead streamToServer.EndRead(ar);            }            if (bytesRead 0) throw new Exception(读取到0字节);            string msg Encoding.Unicode.GetString(buffer, 0, bytesRead);            Console.WriteLine(Received: {0}, msg);            Array.Clear(buffer, 0, buffer.Length);      // 清空缓存避免脏读            lock (streamToServer) {                AsyncCallback callBack new AsyncCallback(ReadComplete);                streamToServer.BeginRead(buffer, 0, BufferSize, callBack, null);            }        } catch (Exception ex) {            if(streamToServer!null)                streamToServer.Dispose();            client.Close();            Console.WriteLine(ex.Message);        }    }} 在上面的SendMessage()方法中我们让它连续发送了三条同样的消息这么仅仅是为了测试因为异步操作同样会出现上面说过的服务器将客户端的请求拆开了的情况。最后我们在Main()方法中创建这个类型的实例然后调用SendMessage()方法进行测试 class Client {    static void Main(string[] args) {        ConsoleKey key;        ServerClient client new ServerClient();        client.SendMessage();                Console.WriteLine(\n\n输入\Q\键退出。);        do {            key Console.ReadKey(true).Key;        } while (key ! ConsoleKey.Q);    }} 是不是感觉很清爽因为良好的代码重构使得程序在复杂程度提高的情况下依然可以在一定程度上保持良好的阅读性。 3.程序测试 最后一步我们先运行服务端接着连续运行两个客户端看看它们的输出分别是什么 大家可以看到在服务端我们可以连接多个客户端同时为它们服务除此以外由接收的字节数发现两个客户端均有两个请求被服务端合并成了一条请求因为我们在其中加入了特殊的协议所以在服务端可以对这种情况进行良好的处理。 在客户端我们没有采取类似的处理所以当客户端收到应答时仍然会发生请求合并的情况。对于这种情况我想大家已经知道该如何处理了就不再多费口舌了。 使用这种定义协议的方式有它的优点但缺点也很明显如果客户知道了这个协议有意地输入[lengthxxx]但是后面的长度却不匹配此时程序就会出错。可选的解决办法是对“[”和“]”进行编码当客户端有意输入这两个字符时我们将它替换成“\[”和“\]”或者别的字符在读取后再将它还原。 关于这个范例就到此结束了剩下的两个范例都将采用异步传输的方式并且会加入更多的协议内容。下一篇我们将介绍如何向服务端发送或接收文件。转载于:https://www.cnblogs.com/kakaliush/archive/2012/03/07/2384489.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/81347.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分类信息网站电子商务网站建设步骤一般为

这两天一直在沉迷于配脚本,由于服务器很多,所以我都是从一台服务器上配置好的脚本直接copy到另一台服务器,按说完全一样的脚本一样的操作,那么应该是一样的执行结果 but, Gul’dan,代…我重启服务器后服务并没有正常启…

做影视网站需要境外疗养院有必要做网站吗

<?php$user$_GET[username]; echo $user; ?> 直接运行改php脚本的话会出现” Notice: Undefined index: username in D:wamp\test\test.php on line 2”的警告,但这是PHP 的提示而非报错&#xff0c;这里我未给$user赋予值,就把它输出,所以报错了。PHP 本身不需要事…

如何建立一个自己的网站鞍山网站网站建设

如果需要学习鸿蒙开发可以查看以下学习资源链接 OpenAtom OpenHarmony Develop applications - HUAWEI HarmonyOS APP 转载请注明出处HarmonyOS(鸿蒙开发&#xff09;入门篇-CSDN博客&#xff0c;谢谢&#xff01;

物流企业网站模板wordpress sae上传图片

无论你要发布播客还是制作高品质的录音&#xff0c;以下任意一款开源应用都能如你所愿。一个稳定的音频编辑器也许并不是你的必需品&#xff0c;但它却能在你的生意场上大显身手。怎么样&#xff1f;使用音频编辑器&#xff0c;你可以添加音频到你的企业网站&#xff0c;创建和…

做网站后期为什么续费中国站免费推广入口

Spring 对请求参数的优雅处方式&#xff08;重写序列化方法&#xff09; 描述前端传参方式介绍代码实现&#xff1a;1、重写序列化方式代码2、设置类自动加载到 Spring 中 描述 在我们日常项目开发过程中&#xff0c;往往会遇到前端请求参数中有空格的情况&#xff0c;前端提交…

南山最专业的网站建设中企动力这个公司怎么样

一、公共英语考试介绍 全国英语等级考试&#xff08;又称公共英语考试&#xff09;设置五个级别和一个附属级&#xff0c;五个级别是&#xff1a; 一级&#xff3b;含一级(B)&#xff0c;即附属级&#xff3d;、二级、三级、四级、五级。 公共英语一级的说明:一级是初始级&…

网站js修改头像代码wordpress评论显示楼层

github或者gitee远程新建空仓库&#xff0c;在本地推送已有的仓库到远程新仓库。 1、远程新建新仓库&#xff0c;例如stm32repo 2、本地仓库添加远程仓库 git remote add origin https://gitee.com/xxxx/stm32repo.git 3、本地仓库完成提交后&#xff0c;推送到远程仓库 gi…

深圳集团网站建设公司WordPress go.php 代码

下列的下载代码示例是 HttpClientSample。它以不同的方式异步调用Web 服务。为了演示本例使用的不同方法&#xff0c;使用了命令行参数。示例代码使用了以下名称空间&#xff1a;System System.Linq System.Net System.Net.Http System.Net.Http.Headers System.Threading Sy…

网站后台需要ie6修改在线平面设计免费

『001』索引-Linux Shell Command shell命令 《01》【线上查询及帮助】【001】-【001】 【001】- 点我快速打开文章【man】【help】【已改版】《02》【文件及目录操作】【002】-【008】 【002】- 点我快速打开文章【ls】【cd】【已改版】【003】- 点我快速打开文章【cp】【find…

网站页面设计报价怎么做网页跳转

问题描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0…

齐河县工程建设监理有限公司网站中国邮政做特产得网站

C - Cats Gym - 102875C 题意&#xff1a; n个猫&#xff0c;猫的身高在1到20之间&#xff0c;现在求这些猫的排列&#xff0c;满足一样高的猫不靠着&#xff0c;且他们之间的最矮的猫不比他们高 输出任意符合条件的排列 题解&#xff1a; 构造题 题目的限制条件决定了&…

徐州网站公司财务系统

转载于:https://www.cnblogs.com/diantao/p/5693877.html

天津建设网站安全员考试查询温州网站改版

Python元类&#xff1a;metaclass 1、类也是对象2、什么是元类3、__metaclass__属性4、自定义元类5、为什么要用metaclass类而不是函数6、究竟为什么要使用元类7、结语 声明&#xff1a; 本文主要参考文章&#xff1a;https://stackoverflow.com/questions/100003/what-are-met…

什么亲子网站可以做一下广告词命理网站开发

目录 一、概述 特点 1、统一存储 2、高扩展性 3、可靠性强 4、高性能 二、准备工作 1、关闭防火墙 2、关闭图形网络管理器 3、配置静态ip 4、关闭selinux 5、修改主机名 6、修改设置 7、ssh免密设置 8、hosts文件修改 9、时间同步 10、添加磁盘&#xff0c;并…

做一个企业网站需要多长时间建e室内设计网官网模型

2024.4.3 题目来源我的题解方法一 深度优先搜索方法二 广度优先遍历 题目来源 力扣每日一题&#xff1b;题序&#xff1a;1379 我的题解 方法一 深度优先搜索 同时对二叉树 original 与 cloned 进行深度优先搜索&#xff0c;如果 original当前搜索的节点的引用等于 target 节…

太原手手工网站建设公司会员管理系统怎么做

从大学毕业起&#xff0c;小编就开始收集各类数据集&#xff0c;经过近几年的积累和沉淀&#xff0c;小编收集整理了32套数据集&#xff0c;内容涵盖“自动驾驶”、“人脸识别”、“世界杯”、“股票数据”、“基因组数据”、“全球各大社交媒体数据”等。现在&#xff0c;小编…

帝国网站管理系统安装连接不上数据库外贸销售工作内容

sklearn与经典机器学习算法 机器学习的利器——sklearn机器学习的7个流程:sklearn的功能主要分为六大部分:目标: 1、掌握sklearn的基本用法 2、掌握线性回归的原理,并进行实践操作 3、理解监督学习经典算法、如K-近邻算法 4、理解非监督学习经典算法机器学习的利器——skle…

怎么建设菠菜网站自己做网站要会什么软件下载

原文地址&#xff1a;HbuilderX 如何使用MUMU模拟器调试--详细配 HbuilderX 如何使用MUMU模拟器调试--详细配置&#xff01;_hbuilderx mumu_一只大黑洋的博客-CSDN博客

外国人做美食视频网站企业网站设计价格

6月1日&#xff0c;2016微软开发者峰会在京召开。 来自微软总部的高层、技术大拿&#xff0c; 以及来自微软亚洲研究院、微软亚太研发集团、Xamarin 总部团队、微软中国开发体验及平台合作事业部的技术专家对各平台的开发进行技术探讨&#xff0c;向开发者展示了一系列引人入胜…