C#: Как я могу сделать другой запрос в моем сокете после его закрытия? - PullRequest
0 голосов
/ 23 января 2020

Я создаю консольное приложение в c# для связи между сервером и клиентом с сокетом.

static void Main(string[] args)
{    
    LoopConnect();
    SendLoop();    
}

private static void SendLoop()
{
    while (true)
    {
        Console.WriteLine("Enter a request: ");
        string req = Console.ReadLine();

        byte[] buffer = Encoding.ASCII.GetBytes(req);
        _clientSocket.Send(buffer,0,buffer.Length,SocketFlags.None);
        _clientSocket.ReceiveTimeout = 10000;

        if (req != string.Empty)
        {
            try
            {
                var receivedBuffer = new byte[2048];
                int rec = _clientSocket.Receive(receivedBuffer, SocketFlags.None);

                byte[] data = new byte[rec];
                Array.Copy(receivedBuffer, data, rec);
                string result = Encoding.ASCII.GetString(data);
                Console.WriteLine("Received : " + result);
                _clientSocket.Shutdown(SocketShutdown.Both);
                _clientSocket.Close();


            }
            catch (SocketException se)
            {
                if (se.SocketErrorCode == SocketError.TimedOut)
                {
                    Console.WriteLine("TIMEOUT");
                    _clientSocket.Shutdown(SocketShutdown.Both);
                    _clientSocket.Close();
                }
            }
        }
    }
}

private static void LoopConnect()
{
    int attempts = 0;
    while (!_clientSocket.Connected)
    {
        try
        {
            attempts++;
            _clientSocket.Connect(IPAddress.Loopback, 100);
        }
        catch (SocketException) {
            Console.Clear();
            Console.WriteLine("Connection attenpts: "+ attempts.ToString());
        }
    }

    Console.Clear();
}

Я делаю первый запрос и получаю свой ответ, но когда я делаю другой запрос У меня есть эта ошибка:

System.ObjectDisposedException: «Не удается получить доступ к удаленному объекту. Имя объекта: 'System. Net .Sockets.Socket'. '

Могу ли я изменить свой код для выполнения запроса после закрытия сокета?

1 Ответ

1 голос
/ 23 января 2020

Переместите LoopConnect(); в while l oop, чтобы получить

...
Console.WriteLine("Enter a request: ");
string req = Console.ReadLine();

LoopConnect();

byte[] buffer = Encoding.ASCII.GetBytes(req);
_clientSocket.Send(buffer,0,buffer.Length,SocketFlags.None);
_clientSocket.ReceiveTimeout = 10000;
...

Это должно гарантировать, что вы открываете сокет всякий раз, когда хотите отправить запрос.

In Кроме того, вы можете захотеть переместить операции выключения и закрытия сокета в блок finally в конце оставшейся попытки, используя

try
{
    var receivedBuffer = new byte[2048];
    int rec = _clientSocket.Receive(receivedBuffer, SocketFlags.None);

    byte[] data = new byte[rec];
    Array.Copy(receivedBuffer, data, rec);
    string result = Encoding.ASCII.GetString(data);
    Console.WriteLine("Received : " + result);
}
catch (SocketException se)
{
    if (se.SocketErrorCode == SocketError.TimedOut)
    {
        Console.WriteLine("TIMEOUT");
    }
}
finally
{
    _clientSocket.Disconnect(true);
}

, поскольку finally больше не использует Shutdown и Close не забудьте освободить ресурсы в конце программы с помощью

static void Main(string[] args)
{    
    LoopConnect();
    SendLoop();   

    _clientSocket.Shutdown(S);
    _clientSocket.Close(SocketShutdown.Both); 
}
...