我正在研究等待客户端连接和接收文件的 TCP 监听器服务。
以下代码用于初始化 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 方法。
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 异常。套接字异常的消息如下。
即使在捕获异常之后,同样的异常也会不断发生。此异常的原因是什么,如何解决?
最佳答案
我不确定为什么会出现问题,但我可以看到您正在使用 Sleep
这将阻止套接字操作(I/O),这可能是您的异常的原因。
试试这个代码,我之前测试过。
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
.BeginListeningInBackground
)。 BeginListeningInBackground
TCPClient
套接字已创建( EndAcceptTcpClient
)并开始读取,以异步方式,检查方法 BeginToReadOnCLient(tcpClient);
. TcpListener
将等待另一个连接:listener.BeginAcceptTcpClient(BeginListeningInBackground, listener);
. 进入方法
BeginToReadOnCLient
读取操作是异步的,使用 NetworkStream
:NetworkStream ns = client.GetStream();
bufferRx = new byte[10];
ns.BeginRead(bufferRx, 0, 10, ReadFromClientStream, ns);
ReadFromClientStream
有一个示例逻辑来读取数据,您必须根据通信协议(protocol)实现正确的逻辑来读取信息。重要 : 在
NetworkStream
中了解如何使用这些异步操作避免此时出现异常:停止 TcpListener,关闭客户端连接,发送或读取信息以及已接收/读取的字节数。
关于c# - TCPListener 在 listener.EndAcceptTcpClient(asyncResult) 上抛出 Socket 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52966108/