【发布时间】:2020-08-18 00:55:47
【问题描述】:
我正在尝试从 UDP 升级到 TCP,但我完全迷路了。 :(
这是我的服务器代码(不要太长)。
private readonly TcpListener _tcpListener;
public TCP(IPEndPoint endPoint)
{
try
{
_tcpListener = new TcpListener(endPoint);
_tcpListener.Start();
AcceptTcpClient();
AcceptSocket();
TestClient test = new TestClient();
test.Connect();
}
catch (SocketException e)
{
Console.WriteLine("SocketException: " + e);
}
finally
{
_tcpListener.Stop();
}
}
private void AcceptSocket()
{
_tcpListener.BeginAcceptSocket(AcceptIncomingSocket, _tcpListener);
}
private void AcceptTcpClient()
{
_tcpListener.BeginAcceptTcpClient(AcceptConnection, _tcpListener);
}
private void AcceptIncomingSocket(IAsyncResult ar)
{
try
{
var clientSocket = _tcpListener.EndAcceptSocket(ar);
Console.WriteLine("Socket accepted: " + clientSocket.Connected);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: " + e);
}
}
private void AcceptConnection(IAsyncResult ar)
{
try
{
if (ar != null)
{
TcpClient client = _tcpListener?.EndAcceptTcpClient(ar);
Console.WriteLine("Connected. " + (client != null && client.Connected));
Console.ReadLine();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: " + e);
}
catch (ObjectDisposedException e)
{
Console.WriteLine("Disposed: " + e);
}
}
这是我的客户端代码:
client = new TcpClient();
client.Connect("127.0.0.1", 2500);
if (client.Connected)
{
Console.WriteLine("TestClient_Connected");
Console.ReadLine();
}
NetworkStream stream = client.GetStream();
byte[] toSend = System.Text.Encoding.ASCII.GetBytes("HELLO THERE");
stream.Write(toSend, 0 , toSend.Length);
byte[] toSend2 = System.Text.Encoding.ASCII.GetBytes("HELLO 2");
stream.Write(toSend2, 0, toSend2.Length);
Console.ReadLine();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
问题是,当我创建客户端实例时,我的服务器不会调用 AcceptConnection,而是调用 AcceptIncomingSocket。之后,当客户端第二次写入时,函数 AcceptConnection 被调用,并抛出此异常:(整个控制台输出,因为调试消息)
TestClient_Connected
Socket accepted: True
Disposed: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.EndAccept(Byte[]& buffer, Int32& bytesTransferred, IAsyncResult asyncResult)
at System.Net.Sockets.TcpListener.EndAcceptTcpClient(IAsyncResult asyncResult)
at ChallengersDeepDedicated.Server.TCP.AcceptConnection(IAsyncResult ar) ```
【问题讨论】:
-
您应该使用 BeginAcceptSocket 或 BeginAcceptTcpClient。发出连接请求时,您可以将其作为套接字或 tcp 客户端(无论您熟悉哪个)接受,但不能同时接受。我会推荐 TcpClient,因为您还可以访问它包装的 Socket 实例。
-
谢谢Oguz,你是对的! :)
标签: c# sockets tcp tcpclient tcplistener