Существующее соединение было принудительно закрыто удаленным хостом - PullRequest
113 голосов
/ 06 апреля 2010

Я работаю с коммерческим приложением, которое выдает исключение SocketException с сообщением,

Существующее соединение было принудительно закрыто удаленным хостом

Это происходит с сокетным соединением между клиентом и сервером. Соединение живое и исправное, передается куча данных, но затем она отключается из ниоткуда.

Кто-нибудь видел это раньше? Какие могут быть причины? Я могу предположить несколько причин, но есть ли способ добавить больше в этот код, чтобы понять, что может быть причиной?

Любые комментарии / идеи приветствуются.

... Последний ...

У меня есть запись из какой-то трассировки .NET,

System.Net.Sockets Verbose: 0 : [8188] Socket#30180123::Send() DateTime=2010-04-07T20:49:48.6317500Z

System.Net.Sockets Error: 0 : [8188] Exception in the Socket#30180123::Send - An existing connection was forcibly closed by the remote host DateTime=2010-04-07T20:49:48.6317500Z 

System.Net.Sockets Verbose: 0 : [8188] Exiting Socket#30180123::Send() -> 0#0

Основываясь на других частях ведения журнала, я видел тот факт, что он говорит, что «0 # 0» означает, что отправляется пакет длиной 0 байт. Но что это на самом деле означает?

Имеется одна из двух возможностей, и я не уверен, какая именно,

1) Соединение закрывается, но затем данные записываются в сокет, что создает исключение выше. 0 # 0 просто означает, что ничего не было отправлено, потому что сокет уже был закрыт.

2) Соединение все еще открыто, и отправляется пакет с нулевыми байтами (т. Е. Код содержит ошибку), а 0 # 0 означает, что пакет с нулевыми байтами пытается быть отправлен.

Что ты считаешь? Я думаю, это может быть неубедительным, но, возможно, кто-то еще видел подобные вещи?

Ответы [ 10 ]

80 голосов
/ 06 апреля 2010

Обычно это означает, что удаленная сторона закрыла соединение (обычно отправляя пакет TCP / IP RST). Если вы работаете со сторонним приложением, вероятные причины:

  • Вы отправляете некорректные данные в приложение
  • Сетевая связь между клиентом и сервером по какой-то причине прерывается
  • Вы вызвали ошибку в стороннем приложении, которая вызвала его сбой
  • Стороннее приложение исчерпало системные ресурсы

Вполне вероятно, что первый случай - это то, что происходит.

Вы можете запустить Wireshark , чтобы точно увидеть, что происходит на проводе, чтобы сузить проблему.

Без более конкретной информации маловероятно, что кто-то здесь действительно сможет вам сильно помочь.

46 голосов
/ 07 июня 2018

Использование TLS 1.2 устранило эту ошибку.
Вы можете принудительно заставить ваше приложение использовать TLS 1.2 с помощью этого (обязательно запустите его перед вызовом службы):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Другое решение:
Включите сильную криптографию на вашем локальном компьютере или сервере, чтобы использовать TLS1.2, потому что по умолчанию он отключен, поэтому используется только TLS1.0.
Чтобы включить надежную криптографию, выполните следующие команды в PowerShell с правами администратора:

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

Вам нужно перезагрузить компьютер, чтобы эти изменения вступили в силу.

26 голосов
/ 15 июня 2011

Это не ошибка в вашем коде. Это происходит от реализации Socket .Net. Если вы используете перегруженную реализацию EndReceive, как показано ниже, вы не получите это исключение.

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }
9 голосов
/ 15 мая 2015

Простое решение для этой распространенной проблемы:

Просто перейдите в файл " .context.cs" (расположенный в " .context.tt", который находится в вашем файле "* .edmx").

Затем добавьте эту строку в ваш конструктор:

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
    }

надеюсь, что это полезно.

8 голосов
/ 09 июня 2017

была такая же ошибка. На самом деле работал в случае, если трафик был отправлен с использованием какого-либо прокси (Fiddler в моем случае) Обновлен .NET Framework с 4.5.2 до> = 4.6, и теперь все работает нормально. Фактический запрос был:
new WebClient().DownloadData("URL");
Исключение составили:

SocketException: существующее соединение было принудительно закрыто удаленный хост

1 голос
/ 30 января 2019

при работе в службе .Net 4.5.2

Для меня проблема усугубилась, поскольку вызов выполнялся в службе .Net 4.5.2. Я последовал предложению @willmaz, но получил новую ошибку.

При запуске службы с включенным ведением журнала я видел, что рукопожатие с целевым сайтом инициировалось бы нормально (и отправлял токен носителя), но на следующем шаге для обработки вызова Post, казалось бы, отбрасывался токен аутентификации сайт ответит Unauthorized.

Оказалось, что учетные данные пула сервисов не имеют прав на изменение TLS (?), И когда я вставил свою локальную учетную запись администратора в пул, все заработало.

1 голос
/ 12 октября 2016

Я получил это исключение из-за циклической ссылки в сущности. В сущности, которая выглядит как

public class Catalog
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public Catalog Parent { get; set; }
    public ICollection<Catalog> ChildCatalogs { get; set; }
}

Я добавил [IgnoreDataMemberAttribute] в свойство Parent. И это решило проблему.

0 голосов
/ 13 апреля 2019

У меня была та же проблема, и мне удалось ее решить в конце концов. В моем случае порт, на который клиент отправляет запрос, не имеет привязки SSL-сертификата. Поэтому я исправил проблему, привязав сертификат SSL к порту на стороне сервера. Как только это было сделано, это исключение исчезло.

0 голосов
/ 06 февраля 2018

Эта ошибка возникала в моем приложении с CIP-протоколом, когда я не отправлял и не получал данные менее чем за 10 секунд.

Это было вызвано использованием метода прямого открытия. Вы можете избежать этого, работая с другим методом, или установить частоту обновления менее 10 с, поддерживающую ваше прямое открытое соединение.

0 голосов
/ 10 марта 2017

Я получил это исключение, когда пытался прочитать строку из базы данных с нулевым значением в столбце перечисления, он не смог отобразить нулевое значение в значение перечисления.

...