Share via


C# Server - TcpClient.Client.Receive - Is there a way to cancel it

Question

Thursday, February 7, 2019 5:45 PM

Hello,

My goal is to start a server with a start button, with an end button immediately stop.
 How do I achieve this?

I have a server that works well.
If I press Abort, set the Cancel flag, it will hang there. This code row.
       sizeReceive = tcpClient.Client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
OK, is a loop and wait for receiving data.

Although I seem to be disconnected, I have to send something.

How can I solve this better? I'm looking for a easy solution.

Best regards Markus

//My forgiven attempts
//Variant 01

private XElement HandleConnection(TcpClient tcpClient, CancellationToken token)
{
    string clientInfo = tcpClient.Client.RemoteEndPoint.ToString();

    IPEndPoint RemAddr = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
    IPEndPoint LocAddr = (IPEndPoint)tcpClient.Client.LocalEndPoint;

    EvHaReceived?.Invoke(this, new ServerEventArgs() { MessageType = MessageTypes.MessageReceived, Message = $"Server:Connection established on port {Port}" });

    try
    {
        tcpClient.LingerState.Enabled = false;
        LogMessage(string.Format("Got connection request from {0}", clientInfo));

        var buffer = new byte[10000];
        int sizeReceive = -1;
        string receiveBuffer = string.Empty;

        while (sizeReceive != 0 && !token.IsCancellationRequested)
        {
            Array.Clear(buffer, 0, buffer.Length);
            try
            {
                sizeReceive = tcpClient.Client.Receive(buffer, 0, buffer.Length, SocketFlags.None);
                

                
//Variant 02               
                
private Socket listener;
private byte[] buffer = new byte[8192]; 

public void StartListening()
{
    listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    listener.Bind(new IPEndPoint(IPAddress.Any, 21));
    listener.Listen(20);
    listener.BeginAccept(OnSocketAccepted, null);
}

public void StoppListening()
{
    listener.Close();    // not working
}

private void OnSocketAccepted(IAsyncResult result)
{
    try
    {
        Socket client = listener.EndAccept(result);


        client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, OnDataReceived, client); // Start receiving data from this client.

        // Start a new async accept operation to accept incoming connections from other clients.
        // listener.BeginAccept(OnSocketAccepted, null); 
    }
    catch (SocketException ex)
    {
        Log.Error($"Error {ex.Message}");
    }
    catch (Exception ex1)
    {
        Log.Error($"Error {ex1.Message}");
    }
}

private void OnDataReceived(IAsyncResult result)
{
    Socket client = result.AsyncState as Socket;
    int received = client.EndReceive(result);

    byte[] buf1 = null;
    buf1 = Encoding.Default.GetBytes("<TEST>tttttt</TEST>");
    client.Send(buf1);

    // Start a new async receive on the client to receive more data.
    client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, OnDataReceived, client);
}               
    

All replies (4)

Friday, February 8, 2019 4:21 AM | 1 vote

Hi Markus ,
Please refer to the following thread :
https://social.msdn.microsoft.com/Forums/vstudio/en-US/5e509e3a-64b6-4a2e-906b-604033cb9094/c-stop-socketaccept?forum=csharpgeneral
More information:
/en-us/dotnet/api/system.net.sockets.socket.close?redirectedfrom=MSDN&view=netframework-4.7.2
I hope it will help you.
Best regards,
Julia

MSDN Community Support Please remember to click Mark as Answer ,the responses that resolved your issue, and to click Unmark as Answer if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].


Friday, February 8, 2019 5:01 PM

Hi Julia,

I'm not sure, need I Dispose?
If yes, before or after Close?

public void Stop()
{
    MyTokenSource.Cancel();

    TcpListenerServer?.Stop();
    TcpClientCustomization?.Client?.Shutdown(SocketShutdown.Both);
    TcpClientCustomization?.Client?.Close();
    TcpClientCustomization?.Client?.Dispose();
}

//On Client site?

public void Close()
{
    TClient?.Client?.Shutdown(SocketShutdown.Both);
    TClient?.Client?.Close();
    TClient?.Client?.Dispose();
    TClient?.Close();

Best regards,
Markus


Monday, February 11, 2019 1:48 AM

Hi Markus ,

Close will automatically call Dispose. But it depends on your needs:

If you use connection object one time, use Dispose.
If connection object must be reused, use Close method.

https://stackoverflow.com/questions/61092/close-and-dispose-which-to-call

I hope it will help you.

Best regards,
Julia

MSDN Community Support Please remember to click Mark as Answer ,the responses that resolved your issue, and to click Unmark as Answer if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].


Monday, February 11, 2019 6:08 AM

Hi Markus Freitag,

**>>I'm not sure, need I Dispose? If yes, before or after Close?

Normally, calling Close internally calls Dispose so you do not need to call both. 

We always call the Shutdown method before closing the Socket.

/en-us/dotnet/api/system.net.sockets.socket.shutdown?view=netframework-4.7.2#System_Net_Sockets_Socket_Shutdown_System_Net_Sockets_SocketShutdown_

Best Regards,

Wendy

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact [email protected].