원격 호스트가 기존 연결을 강제로 닫았습니다.


159

메시지와 함께 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 # 0은 0 바이트의 패킷이 전송되고 있음을 의미합니다.

당신은 무엇을 생각합니까? 결론을 내릴 수는 없지만 다른 누군가가 이런 종류의 것을 보았을 것입니까?


그냥 업데이트. 이 경우 네트워크 설정으로 인해 wireshark가 절단하지 않는 것 같습니다. 그러나 나는 이것을 시도 할 것입니다 : blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx 로그 파일을 생성 해야하는 .NET을 사용하여 추적하는 . 내가 당신을 게시 유지합니다 ...
피터

1
컴캐스트는 P2P 트래픽 엉망 "제로"패킷이 가짜 ID로 위장 보낼 것으로 알려져있다 ---

답변:


98

이것은 일반적으로 원격 측이 연결을 닫았 음을 의미합니다 (일반적으로 TCP / IP RST패킷 을 전송하여 ). 타사 응용 프로그램을 사용하는 경우 가능한 원인은 다음과 같습니다.

  • 응용 프로그램에 잘못된 형식의 데이터를 보내고 있습니다 (HTTPS 요청을 HTTP 서버로 보내는 것을 포함 할 수 있음)
  • 클라이언트와 서버 간의 네트워크 링크가 어떤 이유로 중단됩니다
  • 타사 응용 프로그램에서 버그로 인해 버그가 발생했습니다.
  • 타사 응용 프로그램에서 시스템 리소스를 모두 사용했습니다

첫 번째 경우가 일어날 가능성이 높습니다.

당신은 해고 할 수 와이어 샤크를 문제를 좁힐 와이어에 무슨 일이 일어나고 정확하게 볼 수 있습니다.

더 구체적인 정보가 없으면 여기있는 사람이 실제로 많은 도움을 줄 것 같지 않습니다.


2
큰. 감사. wireshark에 관한 다른 것. 너무 많은 데이터를 수집하는데 어떻게 이런 걸 걸러 낼 수 있을까요? wireshark가 뭔가를 보여 주면 나중에 여기에 게시 할 수 있습니다 ...
peter

4
최소한 IP 주소와 포트 번호로 Wireshark 덤프를 필터링 할 수 있어야합니다. 그 후에 스트림의 끝 부분 (문제가 발생한 부분)을보고 문제가 발생한 부분을 찾을 수있을 때까지 거꾸로 작업하는 것이 가장 도움이됩니다. 관련된 프로토콜의 복잡성에 따라, 거의 불가능한 것이 정말 쉽습니다 ...
RarrRarrRarr

4
글 머리 기호 항목의 출처가 있습니까, 아니면 아래의 게이머의 답변이 목록을 복사 했습니까?
Zack

7
"잘못된 형식의 데이터 보내기" httpshttp서버에 요청을 보내는 것을 의미 할 수 있으며 그 반대의 경우도 마찬가지입니다.
AXMIM

2
필자의 경우 로컬에서 앱을 실행할 때 API를 호출 할 때만이 예외가 발생했습니다. dev, qa 또는 prod 환경에서 문제가 없습니다. 수정? https 대신 http를 로컬로 사용합니다. 로드 밸런서와 관련이 있다고 생각합니다. 그러나 방금 dev, qa 및 prod web.configs를 https에 대한 변환으로 업데이트했습니다. 문제 해결됨.
커쇼

82

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 

이러한 변경 사항을 적용하려면 컴퓨터를 재부팅해야합니다.


1
여러 프로토콜을 지원하기 위해 여러 값을 함께 추가 할 수 있습니다. SSL3에서 TLS1.2까지 모든 것을 지원하려면 SecurityProtocol = (SecurityProtocolType) 4080을 설정하십시오.
Abacus

29

이것은 코드의 버그가 아닙니다. .Net의 소켓 구현에서 온 것입니다. 아래와 같이 오버로드 된 EndReceive 구현을 사용하면이 예외가 발생하지 않습니다.

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }

1
이것은 운영 체제와 궁극적으로 피어에서 나옵니다. 소프트웨어 버그라는 주장에 대한 자세한 설명이 필요합니다.
Lorne의 후작

5
+1. 내 C # 프로그램에서 EndReceive우아한 클라이언트 종료가있을 때 예외가 발생하는 이유에 대해 머리를 두드리고 있었습니다. 이것이 의도적으로 설계된 것은 아닙니다. 정상적인 코드 흐름에서 예외를 던지는 나쁜 디자인이라고 생각합니다. 오버로드 된 방법에 대해 하나님 께 감사드립니다.
Pavan Manjunath

2
@MSaudi 비동기 호출을 사용하고 있으므로 반환되는 데이터를 처리하는 동안 코드가 중지되지 않습니다. 예에서는 msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx를 사용합니다 . 기본적으로 당신은 있어야 StateObject와 클래스 public byte[] buffer = new byte[1024], public Socket socket;와라는 함수를 호출 Receive(Socket s)하지, StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); 그리고에 void ReceiveCallback(IAsyncResult ar)당신 위, 그 코드를 호출합니다.
vapcguy

2
@cagatay 솔루션을 제공하지만 비동기식 방법에서는 가치를 보지 못했습니다. 여기서 Send다른 작업 을 수행하기 전에 수행 한 후 돌아 오는 내용을 즉시 알아야 합니다.
vapcguy

3
실제로 나는이 방법이 완벽하지 않다는 것을 알았습니다. 또한 OP 오류가 발생할 수 있습니다. stackoverflow.com/questions/17790612/…
vapcguy

10

이 일반적인 성가신 문제에 대한 간단한 해결책 :

" .context.cs"파일 ( "* .edmx"파일 아래에있는 " .context.tt"아래에 있음)로 이동하십시오.

그런 다음 생성자에 다음 행을 추가하십시오.

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

이것이 도움이되기를 바랍니다.


@Esi 어디에 넣을까요? 그리고 반환 유형이 없습니까 ??
Khalil Khalaf

2
@FirstStep : Coz 생성자입니다.
Nikhil Agrawal

3
이것은 문제가 발생하는 Entity Framework를 사용하는 사람들에게만 도움 socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);이되며 OP의 문제 인 반환 된 바이트를 간단 하게 읽는 사람들에게는 도움이되지 않습니다 .
vapcguy

ENTITY FRAMEWORK이 솔루션 만 사용하면 작동합니다 !!! 만이 ! 고마워 친구 :)
Rao Hammas

9

같은 버그가 있었다. 실제로 트래픽이 프록시 (내 경우에는 바이올린)를 사용하여 전송 된 경우 작동했습니다. .NET 프레임 워크가 4.5.2에서> = 4.6으로 업데이트되었으며 이제 모든 것이 제대로 작동합니다. 실제 요청은 다음과 같습니다
new WebClient().DownloadData("URL");
. 예외는 다음과 같습니다.

SocketException : 원격 호스트가 기존 연결을 강제로 닫았습니다.


5
이것은 나를 위해 일을 해결하는 한 가지 방법이었습니다. 실제로 기본적으로 사용되는 TLS .NET 버전과 관련이 있습니다. 4.5.2 이하는 TLS 1.0을 사용하는 반면, 4.6 이상은 1.1과 1.2를 허용하는 것이 더 현명합니다. 서버의 TLS 요구 사항을 1.0으로 떨어 뜨려도 문제가 해결되었습니다.
HotN

4

엔티티의 순환 참조로 인해이 예외가 발생했습니다.

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 속성에 추가했습니다. 그리고 그것은 문제를 해결했습니다.


2

.Net 4.5.2 서비스에서 실행중인 경우

전화가 .Net 4.5.2 서비스에서 실행 중이기 때문에 문제가 악화되었습니다. @willmaz 제안을 따랐지만 새로운 오류가 발생했습니다.

로깅이 설정된 상태에서 서비스를 실행하면 대상 사이트와 핸드 쉐이킹이 제대로 시작되고 베어러 토큰을 보내는 것을 보았지만 다음 단계에서 Post call을 처리하면 인증 토큰이 삭제되고 사이트가 로 회신하십시오 Unauthorized.

서비스 풀 자격 증명에 TLS (?)를 변경할 수있는 권한이 없으며 로컬 관리자 계정을 풀에 넣었을 때 모두 작동했습니다.


2

스트림에서 데이터를 읽는 동안이 예외가 발생하면 누구나 도움이 될 수 있습니다. 다음과 같은 루프에서 HttpResponseMessage를 읽을 때이 예외가 발생했습니다.

using (var remoteStream = await response.Content.ReadAsStreamAsync())
using (var content = File.Create(DownloadPath))
{
    var buffer = new byte[1024];
    int read;

    while ((read = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await content.WriteAsync(buffer, 0, read);
        await content.FlushAsync();
    }
}

얼마 후 범인이 버퍼 크기라는 것을 알았습니다. 버퍼 크기가 너무 작아서 약한 Azure 인스턴스와 잘 어울리지 않습니다. 도움이 된 것은 코드를 다음과 같이 변경하는 것이 었습니다.

using (Stream remoteStream = await response.Content.ReadAsStreamAsync())
using (FileStream content = File.Create(DownloadPath))
{
    await remoteStream.CopyToAsync(content);
}

CopyTo () 메서드의 기본 버퍼 크기는 81920입니다. 버퍼가 클수록 프로세스 속도가 빨라지고 전체 다운로드 속도가 증가했기 때문에 오류가 즉시 중지되었습니다. 그러나이 오류를 방지하는 데 다운로드 속도가 중요한 이유는 무엇입니까?

다운로드 속도가 서버가 허용하도록 구성된 최소 임계 값 아래로 떨어지기 때문에 서버와의 연결이 끊어 질 수 있습니다. 예를 들어, 파일을 다운로드하는 응용 프로그램이 IIS에서 호스팅되는 경우 http.sys 구성에 문제가있을 수 있습니다.

"Http.sys는 IIS가 클라이언트와 http 통신을 수행하는 데 사용하는 http 프로토콜 스택입니다. MinBytesPerSecond라는 타이머가 있으며 전송 속도가 kb / sec 임계 값 아래로 떨어지면 연결을 종료하는 역할을합니다. 기본적으로 해당 임계 값은 240kb / sec로 설정되었습니다. "

이 문제는 TFS 개발 팀의이 오래된 블로그 게시물에 설명되어 있으며 IIS와 관련이 있지만 올바른 방향으로 안내 할 수 있습니다. 또한이 HTTP.SYS 속성에 관한 오래된 버그를 언급 : 링크를

Azure 앱 서비스를 사용하고 버퍼 크기를 늘려도 문제가 해결되지 않으면 컴퓨터를 확장 해보십시오. 연결 대역폭을 포함하여 더 많은 리소스가 할당됩니다.


0

나는 같은 문제가 있었고 결국 그것을 해결할 수있었습니다. 필자의 경우 클라이언트가 요청을 보내는 포트에 SSL 인증서 바인딩이 없었습니다. 그래서 SSL 인증서를 서버 측 포트에 바인딩하여 문제를 해결했습니다. 그 일이 끝나면이 예외는 사라졌습니다.


-1

이 오류는 10 초 이내에 데이터를 보내거나받지 않을 때마다 CIP 프로토콜을 사용하는 응용 프로그램에서 발생했습니다.

정방향 방법을 사용했기 때문입니다. 다른 방법으로 작업하거나 정방향 연결을 유지하는 10 초 미만의 업데이트 속도를 설치하여이를 피할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.