本文介绍了TCPListener 在 listener.EndAcceptTcpClient(asyncResult) 上抛出套接字异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 TCP 侦听器服务,它等待客户端连接并接收文件.以下代码用于初始化TCP Listener.

I am working on a TCP Listener Service which waits for client to connect and receive files.The following code is used to initialize TCP Listener.

    var listener= new TcpListener(IPAddress.Any, port);
                    listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
listener.Start();

然后等待客户端

private void WaitForTcpClient(TcpListener listener){
    while(!listener.Pending()){
        Thread.Sleep(500);
    }
    listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);
}

这是方法 BeginListeningInBackground.

This is the method BeginListeningInBackground.

private async void BeginListeningInBackground(IAsyncResult asyncResult){
    var listener = asyncResult.AsyncState as TcpListener;
    var tcpClient = listener.EndAcceptTcpClient(asyncResult);
    Task.Run(() =>
            {
                WaitForTcpClient(listener);
            });
    using (NetworkStream netStream = tcpClient.GetStream()){
    //working with netStream here
    }
}

当我在本地计算机上测试时,它运行良好,但在部署后,它开始给出 Socket Exception.套接字异常的消息如下.即使在捕获异常之后,同样的异常也在不断发生.此异常的原因是什么,如何修复?

It was working great when I tested on my local computer but after deployment, it started giving Socket Exception. The message by socket exception was as following.Even after catching exception, the same exception is constantly occurring. What is the cause of this exception and how can it be fixed?

推荐答案

我不知道为什么会出现问题,但我可以看到您正在使用 Sleep 会阻止套接字操作(I/O),这可能是您异常的原因.

I'm not sure why it is problem, but i can see that you are using Sleep that will block the socket operations (I/O) and it could be the reason of your exception.

试试这个代码,我之前测试过.

try this code, i tested before.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Dummy
{
    public partial class Form1 : Form
    {
        TcpListener listener;
        byte[] bufferRx;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int port = 9982;
            listener = new TcpListener(IPAddress.Any, port);
            listener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            listener.Start();

            //Begin to start the first connection
            System.Console.WriteLine("Waitting for client");
            listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);
        }

        private void BeginListeningInBackground(IAsyncResult asyncResult)
        {
            System.Console.WriteLine("new for client request.");
            var listener = asyncResult.AsyncState as TcpListener;
            var tcpClient = listener.EndAcceptTcpClient(asyncResult);

            BeginToReadOnCLient(tcpClient);

            System.Console.WriteLine("Waitting for next client");
            listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);

        }

        private void BeginToReadOnCLient(TcpClient client)
        {
            System.Console.WriteLine("Initi Rx on Client");

            NetworkStream ns = client.GetStream();
            bufferRx = new byte[10];
            ns.BeginRead(bufferRx, 0, 10, ReadFromClientStream, ns);// (BeginListeningInBackground, listener);
        }

        private void ReadFromClientStream(IAsyncResult asyncResult)
        {
            NetworkStream ns = (NetworkStream)asyncResult.AsyncState;
            System.Console.WriteLine("Read Data from client. DATA:[" + System.Text.Encoding.Default.GetString(bufferRx) + "]");
            bufferRx = new byte[10];
            ns.BeginRead(bufferRx, 0, 10, ReadFromClientStream, ns);
        }
    }
}

我正在使用您的代码以异步方式接受连接请求和读取套接字客户端,而不使用 Sleeps.

I'm using your code to use to accept connections requests and read socket client in asynchronous ways, without use Sleeps.

  1. 启动 Socket Server 并调用异步方法来接受连接 (BeginListeningInBackground).
  2. 进入BeginListeningInBackground创建TCPClientsocket(EndAcceptTcpClient)并开始读取,异步方式检查BeginToReadOnCLient方法(tcpClient);.
  3. 接受连接后,TcpListener 将等待另一个连接:listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);.
  1. Start Socket Server and invoke an asynchronous method to accept connections (BeginListeningInBackground).
  2. Into BeginListeningInBackground the TCPClient socket is created (EndAcceptTcpClient) and start to read, in asynchronous way, check the method BeginToReadOnCLient(tcpClient);.
  3. After accept the the connections the TcpListener will be waiting for another connection: listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);.

进入方法BeginToReadOnCLient读取的操作是异步的,使用NetworkStream:

Into the method BeginToReadOnCLient the operation to read is asynchronous, usin the NetworkStream:

NetworkStream ns = client.GetStream();
bufferRx = new byte[10];
ns.BeginRead(bufferRx, 0, 10, ReadFromClientStream, ns);

ReadFromClientStream 有一个示例逻辑来读取数据,您必须按照通信协议实现正确的逻辑来读取信息.

ReadFromClientStream has a sample logic to read the data, you must implement the correct logic to read the information according with the communication protocol.

重要:阅读有关如何在 NetworkStream 中使用这些异步操作以避免在以下情况发生异常的信息:停止 TcpListener、关闭客户端连接、发送或读取信息以及接收/读取了多少字节.

IMPORTANT: Read about how to use these asynchronous operations in NetworkStream to avoid exception at the moment of: Stop TcpListener, close a client Connection, send or read information and how many bytes have been received/read.

这篇关于TCPListener 在 listener.EndAcceptTcpClient(asyncResult) 上抛出套接字异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 02:41