전송 연결에서 데이터를 읽을 수 없습니다. 기존 연결이 원격 호스트에 의해 강제로 닫혔습니다.


103

서버 앱이 있고 때로는 클라이언트가 연결을 시도 할 때 다음 오류가 발생합니다.

여기에 이미지 설명 입력

참고 : "클라이언트에서 스트림을 가져올 수 없거나 로그인 실패"는 catch 문에 추가 된 텍스트입니다.

중지되는 줄 (sThread : 줄 96)은 다음과 같습니다.

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

이 문제의 원인은 무엇입니까? 항상 발생하는 것은 아닙니다.

답변:


63

이 오류는 일반적으로 대상 컴퓨터가 실행 중이지만 연결하려는 서비스를 사용할 수 없음을 의미합니다. (중지, 충돌 또는 다른 요청으로 사용 중입니다.)

받는 사람 연결 : 영어 기계 되었다하지만 서비스를 사용할 수 없을 때부터 (서비스 실행에서 그 원격 호스트 / 서버 / PC) 에 그 기계, 기계가 요청에 무엇을 해야할지하지 않았다.

기기에 연결할 수없는 경우 다른 오류가 표시됩니다. 나는 그것이 무엇인지 잊어 버렸습니다. 그러나 그것은 "Service Unreachable"또는 "Unavailable"라인을 따라 있습니다.

편집-추가

포트를 차단하는 방화벽이 원인 일 수 있지만 간헐적 ( "때때로 클라이언트가 연결을 시도 할 때")이라고한다면 그럴 가능성은 거의 없습니다. 답장하기 전에 정신적으로 배제했기 때문에 원래 포함하지 않았습니다.


1
문제는 내가 서버를 시작할 때 50 개의 클라이언트가 내 서버에 연결되어 있다는 것입니다. 나는 클라이언트를 받아 들일 때 일종의 대기 신호를 구현했다. while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); ajutor ++; } 클라이언트 = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... 및 Program.waitToFinishAtClient는 클라이언트가 들어있는 스레드에서 수정됩니다
— 알렉스

이것이 "기다림"이 문제 일 수 있습니까?
— Alex

1
그냥 놔둬 야하나요? 기다려?
— Alex

1
기다림이 문제라고 생각합니다. 나는 확실히 당신의 코드를 충분히 알지 못하지만 확실하게 들릴 것입니다. 자신 만의 서비스를 "어려운 방식"으로 구축했는지 아니면 WCF를 사용하는지 아니면 Remoting을 사용하는지 궁금합니다.
— David

여기에있는 약간의 코드를 기반으로 할 때 "대기"문제가 각 연결에 대해 별도의 스레드 내에 있으면 피할 수있는 것처럼 보입니다. 추측이 옳은 경우를 대비하여 다음은 도움이 될 수있는 다중 스레딩이있는 다중 스레드 TCP 서비스의 예입니다. switchonthecode.com/tutorials/…
— David

180

웹 서비스를 호출 할 때이 오류가 발생했습니다. 이 문제는 전송 수준 보안과도 관련이 있습니다. 웹 사이트 프로젝트를 통해 웹 서비스를 호출 할 수 있지만 테스트 프로젝트에서 동일한 코드를 재사용하면이 메시지가 포함 된 WebException이 발생합니다. 전화를 걸기 전에 다음 줄을 추가하면 문제가 해결되었습니다.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

편집하다

System.Net.ServicePointManager.SecurityProtocol- 이 속성은 HTTPS (Secure Hypertext Transfer Protocol) 체계 만 사용하는 새 연결에 사용할 SSL (Secure Sockets Layer) 또는 TLS (전송 계층 보안) 프로토콜의 버전을 선택합니다. 기존 연결은 변경되지 않습니다.

SecurityProtocol프로토콜 버전을 선택할 때 TLS 핸드 셰이크 중에 구성이 중요 하다고 생각합니다 .

TLS 핸드 셰이크 -이 프로토콜은 TLS 에 의한 실제 애플리케이션 데이터 교환을 위해 양측에서 필요한 모든 정보를 교환하는 데 사용됩니다.

ClientHello- 클라이언트가 지원하는 가장 높은 TLS 프로토콜 버전을 지정하는 ClientHello 메시지를 보냅니다.

ServerHello- 서버는 선택한 프로토콜 버전을 포함하는 ServerHello 메시지로 응답합니다. 선택한 프로토콜 버전은 클라이언트와 서버가 모두 지원하는 것 중 가장 높아야합니다. 예를 들어 클라이언트가 TLS 버전 1.1을 지원하고 서버가 버전 1.2를 지원하는 경우 버전 1.1을 선택해야합니다. 버전 1.2는 선택하지 않아야합니다.


8
이것은 나를 구했다! 감사합니다. 내 디버거에서 테스트하는 동안 https 서비스를 호출하려고하는데 OP에 문제가 있습니다.
— Blair Holmes

6
이것이 작동하는 방법 / 이유에 대해 더 많이 알고 있습니까? PostAsync 호출로 어려움을 겪고 있으며 내 오류도 수정되는 것으로 보입니다. 효과가있어 다행이지만 이유도 알고 싶습니다.
— Kevin Matlock

1
@HansVonn 감사합니다! 시간 절약-작동 이유와 관련하여 연결할 때 사용하는 TLS 버전을 제한하는 것입니다.
— confusedandamused

1
이것이 나를 다시 한번 얻었다는 것을 믿을 수 없다! 감사합니다
— Sergio A.

2
감사합니다! 이것은 나를 미치게 만들었다.
— mknopf

34

내 특정 사례 시나리오는 Azure 앱 서비스의 최소 TLS 버전이 1.2로 변경된 것입니다.

지금부터 이것이 기본값인지는 모르겠지만 다시 1.0으로 변경하면 작동합니다.

"SSL 설정"에서 설정에 액세스 할 수 있습니다.


7
오 마이 갓 정말 감사합니다! 나는 이것에 너무 오래 머물렀고 웹 앱의 SSL 설정을 확인했으며 최소값은 1.0이 아닌 1.2로 설정되었습니다. 1.0으로 다시 변경하고 웹 앱을 다시 시작하면 작동했습니다! 정말 고맙습니다!
— Mason

1
감사합니다, @ hugo-hilário, 놀랍게도 저에게도 효과가있었습니다! 도대체 어떻게 그렇게 까다로운 해결책을 찾았습니까! : D
— hosjay

@hosjay 그것은 나에게도 지옥이었습니다 :)
— Hugo Hilário

3
내 친구를 구했습니다!
— Nitesh

내 Azure Function v2
— Pieter Heemeryck

17

이 블로그 게시물의 수정 사항 중 어느 것이 도움이되었는지 확실하지 않지만 그중 하나 가이 문제를 정렬했습니다 ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

나를 도운 트릭은 WebRequest 사용을 중단하고 대신 HttpWebRequest를 사용하는 것입니다. HttpWebRequest를 사용하면 세 가지 중요한 설정을 사용할 수 있습니다.

과

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

  • 1 단계 : KeepAlive 비활성화
  • 2 단계 : ProtocolVersion을 Version10으로 설정
  • 3 단계 : 서비스 지점 수 제한

1
이 답변이 저에게 동일한 문제를 해결 한 것입니다. IIS7의 Http 응답 헤더 섹션에서 'Keep Alive'를 해제했습니다
— drzounds

또한 해당 동작이있는 웹 서비스의 Reference.cs에이 코드를 추가해야했습니다. 보호 된 재정의 System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = false; return webRequest; }
— drzounds

11

Google 서버 중 하나에서 HTTPS 서비스를 호출하면 " 전송 연결에서 데이터를 읽을 수 없습니다. 기존 연결이 강제로 닫혔습니다. "예외가 발생했습니다. 하지만 HTTP 서비스는 잘 작동했습니다. Wireshark를 사용하여 TLS 핸드 셰이크 실패인지 확인했습니다. 결국 서버의 암호화 제품군을 업데이트해야했습니다.


이것이 저에게 일어난 일입니다. A가 만료 된 인증서를 SSL 연결로 전송했습니다. 인증서를 갱신하고 작동했습니다.
— Guilherme 드 예수 산토스

8

"Hans Vonn"에 따르면 대답합니다.

전화를 걸기 전에 다음 줄을 추가하면 문제가 해결되었습니다.

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

보안 프로토콜을 추가하고 정상적으로 작동하지만 건강하지 않은 모든 API 호출 전에 추가해야합니다. .net 프레임 워크 버전을 4.6 이상으로 업그레이드하고 예상대로 작동하기 위해 모든 API 호출 전에 추가 할 필요가 없습니다.


1
대단히 감사합니다. 당신은 내 하루를 만들었습니다. 이 전에 방화벽 비활성화 및 ServicePointManager.ServerCertificateValidationCallback 추가 테스트도 테스트했지만 작동하지 않았다고 언급하면 ​​유용 할 수 있습니다.
— Tekin

5

간헐적 인 문제에는 도움이되지 않지만 비슷한 문제가있는 다른 사람들에게는 유용 할 수 있습니다.

VM을 복제하고 새 IP 주소로 다른 네트워크에서 시작했지만 IIS에서 바인딩을 변경하지 않았습니다. Fiddler는 "전송 연결에서 데이터를 읽을 수 없습니다 : 기존 연결이 원격 호스트에 의해 강제로 닫혔습니다"를 표시하고 IE는 "고급 설정에서 TLS 1.0, TLS 1.1 및 TLS 1.2를 켜십시오"라고 말했습니다. 새 IP 주소에 대한 바인딩을 변경하면 문제가 해결되었습니다.


2

어떤 이유로 서버와의 연결이 끊어졌습니다. 서버가 명시 적으로 연결을 종료했거나 서버의 버그로 인해 연결이 예기치 않게 종료되었을 수 있습니다. 또는 클라이언트와 서버 (스위치 또는 라우터) 사이의 무언가가 연결을 끊었습니다.

문제를 일으킨 서버 코드 일 수도 있고 그렇지 않을 수도 있습니다. 서버 코드에 대한 액세스 권한이있는 경우 클라이언트 연결이 닫힐 때 알려주는 디버깅을 거기에 넣을 수 있습니다. 그러면 연결이 끊어지는시기와 이유를 알 수 있습니다.

클라이언트에서는 언제든지 서버가 실패 할 가능성을 고려하여 코드를 작성해야합니다. 이것이 바로 그 방법입니다. 네트워크 연결은 본질적으로 신뢰할 수 없습니다.


2

이것은 내 문제를 해결했습니다. 요청하기 전에 다음 줄을 추가했습니다.

System.Net.ServicePointManager.Expect100Continue = false;

100-continue 동작을 지원하지 않는 프록시가 서버에있는 것 같습니다.


1

나는 과거에 그 문제를 얻었습니다. PostgreSQL을 사용하고 있습니다. 하고 있으며 프로그램을 실행할 때 때로는 연결되고 때로는 이와 같은 오류가 발생합니다.

내 코드를 실험 할 때 공개 양식 아래의 첫 번째 줄에 연결 코드를 넣었습니다. 다음은 예입니다.

전에:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

지금:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

나는 프로그램이 어떤 일을하기 전에 먼저 연결을 읽어야한다고 생각한다. 나는 내가 틀렸다면 나를 바로 잡는다. 그러나 내 연구에 따르면 이것은 코드 문제가 아니라 실제로 기계 자체에서 발생했습니다.

행복한 코딩!


1
System.Net.ServicePointManager.Expect100Continue = false;

이 문제는 웹 서버에 프록시 서버가 구현되어 있기 때문에 때때로 발생합니다. 송신 서비스를 호출하기 전에이 행을 입력하여 프록시 서버를 우회합니다.


0

전송되는 요청을 확인하기 위해 타사 응용 프로그램 (Fiddler)을 실행했습니다. 이 응용 프로그램을 닫으면 문제가 해결되었습니다.


0

클라이언트의 웹 사이트가 웹 API 서비스에 연결을 시도하고 동일한 메시지를받는 매우 유사한 문제가 발생했습니다. 이것은 IIS가 실행되는 서버에 코드 변경이나 Windows 업데이트가 없었을 때 완전히 갑자기 시작되었습니다.

우리의 경우 호출 웹 사이트가 TLS 1.0 만 지원하는 .Net 버전을 사용하고 있었으며 어떤 이유로 IIS가 실행되고있는 서버가 TLS 1.0 호출 수신을 중지 한 것으로 나타났습니다. 진단하려면 IIS 서버의 레지스트리를 통해 명시 적으로 TLS를 활성화 한 다음 해당 서버를 다시 시작해야합니다. 다음은 reg 키입니다.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:


    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

여기 에 다른 질문에 대한 내 대답 에는 항목을 추가하는 데 사용한이 powershell 스크립트가 있습니다.

참고 : 이전 보안 프로토콜을 사용하는 것은 좋은 생각이 아닙니다. 우리의 경우 정답은 클라이언트 웹 사이트에서 TLS 1.2를 사용하도록 코드를 업데이트하는 것이었지만 위의 레지스트리 항목은 처음부터 문제를 진단하는 데 도움이 될 수 있습니다.


0

이것이 나에게 일어난 이유는 DI 공급자에게 재귀 적 종속성이 있었기 때문입니다. 제 경우에는 :

services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());

두 번째 범위 서비스 등록 만 제거하는 것이 수정되었습니다.

services.AddScoped(provider => new CfDbContext(builder.Options));

0

도메인에 https 인증서가있는 경우 IIS의 도메인 이름에 대한 https 바인딩이 있는지 확인하십시오. IIS에서-> 도메인 선택-> Bindings Site Bindings 창이 열립니다. https에 대한 바인딩을 추가하십시오.


0

비슷한 문제가 있었고 내가 사용한 앱과 방화벽 /로드 밸런서를 우회했는지 여부에 따라 다음과 같은 오류가 발생했습니다.

[blah] (# 136의 경우)에 대한 HTTPS 핸드 셰이크에 실패했습니다. System.IO.IOException 전송 연결에서 데이터를 읽을 수 없습니다. 기존 연결이 원격 호스트에 의해 강제로 닫혔습니다.

과

ReadResponse () 실패 : 서버가이 요청에 대한 완전한 응답을 반환하지 않았습니다. 서버에서 0 바이트를 반환했습니다.

문제는 SSL 서버 인증서가 누락되어 두 대의 서버에 설치되지 않은 것으로 밝혀졌습니다.


0

처음에 핸드 셰이크를 설정할 수 있는지 확인하십시오. 이전에 파일을 업로드 할 때이 문제가 있었는데 업로드를 제거하고 매개 변수가 주어지면 로그인 할 수 있는지 확인했을 때 문제가 존재하지 않는 경로라는 것만 알아 냈습니다.



0

저에게는 IIS 바인딩에서 웹 서버의 IP 주소가있는 문제였습니다. 할당되지 않은 모든 IP를 사용하도록 변경했고 애플리케이션이 작동하기 시작했습니다.


0

adomd를 사용하여 Microsoft 분석 서비스에 mdx 쿼리를 실행하는 python clr에서 오류가 발생했습니다.

Hans Vonn의 도움으로 해결 했으며 여기에 파이썬 버전이 있습니다.

clr.AddReference("System.Net")
from System.Net import ServicePointManager, SecurityProtocolType 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

0

나중에 이것을 찾을 수있는 사람들을 위해 .NET 버전 4.6 이후에도이 문제가 발생했습니다.

web.config 파일에서 다음 행을 확인하십시오.

<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5" />

서버에서 4.6.x 이상의 .NET 버전을 실행중인 경우 서버의 프레임 워크 버전과 일치하도록 이러한 targetFramework 값을 조정해야합니다. 버전이 4.6.x 미만인 경우 코드가 이전 버전 (이 경우 업데이트를 고려해야 함)에 의존하지 않는 한 .NET을 업그레이드하고 최신 버전을 사용하는 것이 좋습니다.

targetFrameworks를 4.7.2로 변경하고 문제가 사라졌습니다.

<compilation debug="true" targetFramework="4.7.2">
...
<httpRuntime targetFramework="4.7.2" />

최신 프레임 워크는 사용 가능한 최상의 프로토콜을 사용하고 안전하지 않거나 사용되지 않는 프로토콜을 차단하여이 문제를 분류합니다. 연결하거나 호출하려는 원격 서비스에서이 오류가 발생하면 더 이상 이전 프로토콜을 지원하지 않을 수 있습니다.

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