我回顾过我当时参与的过去的线程 但仍然很难找到解决方案。据我所知,我必须为客户端提供一个公共共享的ManualResetEvent对象,以及实现一个状态对象传递给BeginRead方法的。但是就我所知道的那样,就像我知道的那样,一旦我有一个客户端连接到我的服务器,它就会很难正确关闭,因为引用仍然是飞行的。关于。 这是我目前实施的简要概述... 服务器) *包含一组客户对象 1)Astart调用方法,其中包含一个参数,用于监听 本地端口 2)启动后台线程,循环不断调用 "连接"新客户端对象的方法并将其传递给TCP侦听器 AcceptTcpClient结果。 3)一旦客户端连接其事件处理程序,就会初始化它 存储在集合对象中。然后引发一个事件来通知客户刚刚连接的 主应用程序。 客户端) )A连接调用方法,其中包含一个已经初始化的 TcpClient对象,该对象将由服务器传递。 2)调用TcpClients GetStream.BeginRead方法并且 创建了IAsyncResult对象,它存储在模块中。等级。 3)当数据收到时,引发TcpClients BeginRead异步回调,如果数据长度为0,则客户端被认为是 断开连接,否则会引发一个事件,通知服务器从客户端收到的数据是,并且再次启动BeginRead方法。 I创建了一个状态对象,其中包含1个公共属性 布尔类型称为abortRequested但我不确定如何实现这个。 如果我创建一个名为close的公共方法对于客户来说它应该包含什么?b $ b?对不起这篇长篇文章,但我非常期待获得* a *方法 正在工作,因为我好像在圈子里走来走去!提前感谢加载!!! 尼克。 解决方案 嗨尼克, 1)Aconnect调用方法,它包含一个已经由服务器传递的已经 initializedTcpClient对象。 我对上面的行有点困惑,为什么我们需要传递 从服务器到客户端的TcpClient对象? 在您的方案中,似乎我们的模型如下所示。 客户端服务器 新的TcpClient(A)-------------------------> TCPListener | | -----> TcpClient(B) 然后A将与B通信。 这里有两个样本你可以看看。 异步TCP套接字服务器 http://www.gotdotnet.com/Community/你... mpleGuid = d789d 245-4cf7-45af-9660-c375fc3f796c 多线程VB.NET TCP / IP侦听器 http://www.gotdotnet.com /Community/U...mpleGuid=75e68 966-d567-47b3-a255-9a51f9cb0eb7 到目前为止.NET框架没有支持取消异步 回调(即BeginRead和EndRead)。 但是我们可以设置较少的读取单位,这样每次BeginRead都会 尝试读取单位字节数来自网络流。 ,例如(只是一个例子)我们可以将值设置为1,即每个 BeginRead一个字节,然后在异步回调中调用EndRead之后(因为 只需一个字节快速返回),然后我们可以检查bool值为 看看我们是否需要中止读取操作,如果是,我们可以关闭 tcpclient和Asynchronous回调将退出,否则我们可以继续阅读 下一个字节。 如果您仍有任何疑虑,请随时告诉我。 /> 祝你好运, Peter Huang 微软在线合作伙伴支持 安全! - www.microsoft.com/security 此帖子原样是按原样提供的。没有保证,也没有赋予任何权利。 嗨彼得, 很棒,我希望你的响应,因为你似乎已经分享了关于这个主题的知识。 到目前为止,.NET框架不支持取消异步回调(即BeginRead和EndRead)。但是我们可以将读取单位设置得更少,这样每次BeginRead都会尝试从网络流中读取单位字节数。 哇!现在这让我很难过,请问您是否知道BeginRead的底层 机制是什么?它是否只是简单地启动一个线程,它不断地检查流,看看它中有多少数据,当它达到某个阈值时,回调会被触发? 可以模拟这种机制吗?我可以制作自己的BeginRead,可以取消而不会有任何问题吗?或者这需要使用 "套接字"类而不是TCPClient? 例如(只是一个例子)我们可以将值设置为1,即每个BeginRead一个字节,然后在异步回调中调用EndRead之后(因为它只会快速返回一个字节),然后我们可以检查一个bool值来看看我们是否需要中止读取操作,如果为true,我们可以关闭tcpclient并且异步回调将退出,否则我们可以继续读取下一个字节。 所以通过这种方法取消的唯一方法是将回调设置为 为1个字节并向*发送消息*强制回调是 调用?也许甚至发送一条特定的消息来关闭服务器,它好像是一个非常奇怪的方式,但如果这是唯一的方式,那么我将会b / b 。当然其他人有这个问题?你怎么会在没有使用Asynchronous 回调的情况下在套接字上执行异步读取? 感谢您的帮助: - ) 尼克。 嗨尼克, BeginRead有点像异步回调。通常我们可以认为它类似于我们创建一个新线程并在 线程中调用Read方法的。在我们调用BeginRead之后,系统将运行一个线程(来自系统管理的 线程池)来调用线程中的回调函数 并调用EndRead来尝试重新检索数据(正如我们称之为 Read,如果没有数据到达,它将被阻止,因此称为BeginRead的的主线程将继续运行。所以在我们调用BeginRead之后,回调将被称为 ,而不是在数据到达之后。虽然我们可以创建一个新线程并调用read方法,当我们调用read方法时想要中止 读取操作,我们可以直接中止线程,但是这个方法不建议使用,因为这可能会导致某些资源无法正常清理。 /> 更好的方法是让线程自行退出,即我在每次读取几个字节之前建议 并评估bool值以了解我们是否 需要退出线程。在上一篇文章中,我建议每次一个字节,即 只是一个例子,因为如果我们每次读取1 MB,它将给我们更少的机会取消读取操作,因为1 MB可能需要更长时间 完成读取的时间超过1个字节。因此,根据网络连接状态,带宽, 。您可以尝试使用 myNetworkStream.DataAvailable来评估数据是否可用,因为如果myNetworkStream.DataAvailable为false,则为,将阻止EndRead 直到有数据到达。 以下是三种方法的msdn文档,你可以试着比较 用BeginRead和EndRead读取,(链接中还有示例代码) NetworkStream.Read方法 http://msdn.microsoft.com/library/de...us/cpref/html/ frlrfsystemnetsocketsnetworkstreamclassreadtopic.a sp NetworkStream.EndRead http://msdn.microsoft.com/library/de...us/cpref/html/ frlrfsystemnetsocketsnetworkstreamclassreadtopic.a sp NetworkStream .BeginRead方法 http://msdn.microsoft.com/library/de...us/cpref/html/ frlrfsystemnetsocketsnetworkstreamclassreadtopic.a sp 祝你好运, Peter Huang 微软在线合作伙伴支持 安全! - www.microsoft.com/security 此帖子原样是按原样提供的。没有保证,也没有授予任何权利。 Hi there,After recently coming across issues with implementing a UDP server forinterprocess communication; involving file transfer, I have decided to goonto TCP.Now I *have* created a TCP server in the past for VB.NET but hadtroubles when it comes to disconnecting all clients and cleaning upremaining references. The problems arrise when using the IAsyncResult forreceiving data, once started a method is needed to successfully stop it at*any* time.I have looked back on past threads that I was involved in at the timebut still struggle to find the solution. As I understand it, I have to havea public shared ManualResetEvent object for the client, as well asimplementing a state object to pass to the BeginRead method. But that isabout as much as I know, once I have a client connected to my server itstruggles to close correctly, as references are still "flying" about.This is a brief outline of my current implementation...Server)* Contains a collection of client objects1) A "start" method is called which contains a parameter for thelocal port to listen on2) A background thread is started which loops continuously callingthe "connect" method of a new client object and passing it the TCP listenersAcceptTcpClient result.3) Once a client connects its event handlers are initialized and itis stored into the collection object. An event is then raised to notify themain application that a client has just connected.Client)1) A "connect" method is called which contains an already initializedTcpClient object which is to be passed by the server.2) The TcpClients GetStream.BeginRead method is called and anIAsyncResult object is created, this is stored in "module" level.3) The TcpClients BeginRead async callback is raised when data isrecieved, if the data is 0 in length then the client is considered to bedisconnecting, otherwise an event is raised notifying the server of therecieved data from the client and the BeginRead method is started again.I have created a state object which contains 1 public property ofboolean type called "abortRequested" but I am unsure how to implement this.If I create a public method called "close" for the client what should itcontain? Sorry for this long post but I am very eagre to get *a* methodworking as I seem to be going around in circles! Thanks loads in advance!!!Nick. 解决方案 Hi Nick, 1) A "connect" method is called which contains an alreadyinitializedTcpClient object which is to be passed by the server.I am somewhat confused about the line above, why we need to pass theTcpClient object from the server to the client?In your scenario, it seems that we have the model as below.Client Servernew TcpClient(A) -------------------------> TCPListener||----->TcpClient (B)Then the A will communicate with B.Here are two samples you may have a look.Async TCP Socket Server http://www.gotdotnet.com/Community/U...mpleGuid=d789d245-4cf7-45af-9660-c375fc3f796cMulti Threaded VB.NET TCP/IP Listener http://www.gotdotnet.com/Community/U...mpleGuid=75e68966-d567-47b3-a255-9a51f9cb0eb7So far .NET framework did not support canceling an AsynchronousCallback(i.e. the BeginRead and EndRead).But we can set the read unit less, so that every time the BeginRead willtry to read the unit count of bytes from the networkstream.e.g. (Just an example) we can set the value to 1, i.e. one byte perBeginRead, then after EndRead call in the Asynchronous Callback(becausejust one byte it will return quickly), then we can check a bool value tosee if we need to abort the read operation, if true, we can just close thetcpclient and the Asynchronous Callback will exit, else we can keep readthe next byte.If you still have any concern, please feel free to let me know.Best regards,Peter HuangMicrosoft Online Partner SupportGet Secure! - www.microsoft.com/securityThis posting is provided "AS IS" with no warranties, and confers no rights. Hi Peter,Excellent, I was hoping for your response as you seem to have allot ofknowledge on this subject. So far .NET framework did not support canceling an Asynchronous Callback(i.e. the BeginRead and EndRead). But we can set the read unit less, so that every time the BeginRead will try to read the unit count of bytes from the networkstream.Wow! Now that suprises me, may I ask if you know what the underlyingmechanism is for BeginRead? Does it simply start a thread which constantlychecks the stream to seem how much data is in it, and when it reaches acertain threshold the callback is fired?Can this mechanism be simulated? Could I make my own BeginRead that canbe cancelled without any problems? Or would this require using the"sockets" classes rather than TCPClient? e.g. (Just an example) we can set the value to 1, i.e. one byte per BeginRead, then after EndRead call in the Asynchronous Callback(because just one byte it will return quickly), then we can check a bool value to see if we need to abort the read operation, if true, we can just close the tcpclient and the Asynchronous Callback will exit, else we can keep read the next byte.So the only way to cancel via this method would be to set the callbackto 1 byte and send a message to *yourself* to force the callback to beinvoked? Maybe even send a particular message to shut down the server, itseems a pretty weird way of doing it but if it is the only way then I shallhave to. Surely other people have had this problem? How else would youperform an asynchronous read on a socket without using the Asynchronouscallbacks?Thanks for your help :-)Nick.Hi Nick,BeginRead is kind of asynchronout callback. Usually we can consider itsimilar as that we create a new thread and call the Read method in thethread. After we call the BeginRead, the system will run a thread(From thethreadpool managed by system) to call the callback function in the threadand EndRead was called to attempt to retrieve data back(just as we call theRead, it will be blocked if no data arrived , so that the mainthread thatcalled the BeginRead will keep running. So the callback will be calledafter we call the BeginRead, not after the data is arrived. Although we cancreate a new thread and call the read method, and when we want to abort theread operation, we can just abort the thread, but the method is notrecommended, because this may cause some resources not cleaned properly. Abetter method is to let the thread exit itself, i.e. I have suggestedbefore read a few bytes everytime and evaluate a bool value to know if weneed exit the thread. In the last post I suggest one byte per time, that isjust a example, because if we read 1 MB per time, it will give us lessopportunity to cancel the read operation, because the 1 MB may take longertime to complete reading than 1 byte. So the proper value should be decidedby your own according to the network connectivity status, bandwidth,network adapt and so on. You may try to use themyNetworkStream.DataAvailable to evaluate if the data is available, becauseif myNetworkStream.DataAvailable is false, the EndRead will be blockeduntil there is data arrived.Here are the msdn documents for the three methods, you may try to compareRead with BeginRead and EndRead,(Also there are example code in the links)NetworkStream.Read Method http://msdn.microsoft.com/library/de...us/cpref/html/frlrfsystemnetsocketsnetworkstreamclassreadtopic.a spNetworkStream.EndRead http://msdn.microsoft.com/library/de...us/cpref/html/frlrfsystemnetsocketsnetworkstreamclassreadtopic.a spNetworkStream.BeginRead Method http://msdn.microsoft.com/library/de...us/cpref/html/frlrfsystemnetsocketsnetworkstreamclassreadtopic.a spBest regards,Peter HuangMicrosoft Online Partner SupportGet Secure! - www.microsoft.com/securityThis posting is provided "AS IS" with no warranties, and confers no rights. 这篇关于远离UDP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-25 21:19