问题
I'm trying to upgrade from UDP to TCP, but I am completely lost. :(
This is my Server code (not too long).
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);
}
}
and here is my client code:
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);
}
The problem is, when I create the client instance, my server won't call the AcceptConnection, but instead it calls AcceptIncomingSocket. After that when the client's second write comes in the function AcceptConnection is called, and throws this exception: (Whole console output, because of the debug messages)
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) ```
回答1:
I would recommend you to take a look at the Microsoft docs, there are good examples of asynchronous socket client and server:
Server: https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example
Client: https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example
Writing a socket client-server program could be tricky. For having a good implementation I would recommend you dive into details and learn how it works and how properly use it.
I'm sure going over the docs would be useful and will help you understand the concept of sockets.
After reading that, check the new high-performance System.IO.Pipelines library that manages the buffer for you and make your life easier:
https://devblogs.microsoft.com/dotnet/system-io-pipelines-high-performance-io-in-net//#comment-5471
来源:https://stackoverflow.com/questions/61577988/c-sharp-tcp-beginaccepttcpclient-throws-objectdisposedexception