我正在查看使用socketasynceventargs的服务器的源代码,我正在试图弄清楚这不会导致堆栈溢出:
因此调用此代码以允许套接字接受传入连接(向下滚动到底部以查看我的意思):
/// <summary> /// Begins an operation to accept a connection request from the client. /// </summary> /// <param name="acceptEventArg">The context object to use when issuing /// the accept operation on the server's listening socket.</param> private void StartAccept(socketasynceventargs acceptEventArg) { if (acceptEventArg == null) { acceptEventArg = new socketasynceventargs(); acceptEventArg.Completed += new EventHandler<socketasynceventargs>(OnAcceptCompleted); } else { // Socket must be cleared since the context object is being reused. acceptEventArg.AcceptSocket = null; } this.semaphoreAcceptedClients.WaitOne(); Boolean willRaiseEvent = this.listenSocket.AcceptAsync(acceptEventArg); if (!willRaiseEvent) { this.ProcessAccept(acceptEventArg); } }
/// <summary> /// Process the accept for the socket listener. /// </summary> /// <param name="e">SocketAsyncEventArg associated with the completed accept operation.</param> private void ProcessAccept(socketasynceventargs e) { if (e.BytesTransferred > 0) { Interlocked.Increment(ref this.numConnectedSockets); Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",this.numConnectedSockets); } // Get the socket for the accepted client connection and put it into the // ReadEventArg object user token. socketasynceventargs readEventArgs = this.readWritePool.Pop(); readEventArgs.UserToken = e.AcceptSocket; // As soon as the client is connected,post a receive to the connection. Boolean willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs); if (!willRaiseEvent) { this.ProcessReceive(readEventArgs); } // Accept the next connection request. this.StartAccept(e); // <==== tail end recursive? }
看最后一行.它再次调用顶级函数.这怎么不通过这两个函数之间的来回乒乓来溢出堆栈?它似乎是尾端递归,但这不是Haskell所以我不知道这是如何工作的.
我的理解是,这些并没有在线程中被触发,而是由cpu一次执行一次.
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。