Không thể đọc dữ liệu từ kết nối truyền tải: Một kết nối hiện có đã bị máy chủ từ xa buộc đóng


103

Tôi có một ứng dụng máy chủ và đôi khi, khi máy khách cố gắng kết nối, tôi gặp lỗi sau:

nhập mô tả hình ảnh ở đây

LƯU Ý: "không thể tải luồng từ ứng dụng khách hoặc đăng nhập không thành công" là văn bản được tôi thêm vào trong câu lệnh tóm tắt

và dòng tại đó nó dừng lại (sThread: dòng 96) là:

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

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

Điều gì có thể gây ra vấn đề này? Lưu ý rằng nó không xảy ra mọi lúc

Câu trả lời:


63

Lỗi này thường có nghĩa là máy mục tiêu đang chạy, nhưng dịch vụ bạn đang cố gắng kết nối không khả dụng. (Có thể là nó đã dừng, gặp sự cố hoặc đang bận với một yêu cầu khác.)

Bằng tiếng Anh: Kết nối với máy (máy chủ / máy chủ / PC từ xa mà dịch vụ chạy) đã được thực hiện nhưng vì dịch vụ không khả dụng trên máy đó nên máy không biết phải làm gì với yêu cầu.

Nếu kết nối với máy không khả dụng, bạn sẽ thấy một lỗi khác. Tôi quên nó là gì, nhưng nó nằm dọc theo dòng "Dịch vụ không thể truy cập" hoặc "Không khả dụng".

Chỉnh sửa - đã thêm

Có thể điều này là do tường lửa chặn cổng, nhưng nếu bạn nói rằng nó không liên tục ("đôi khi máy khách cố gắng kết nối"), điều đó rất khó xảy ra. Tôi không bao gồm điều đó ban đầu bởi vì tôi đã loại trừ nó trong tâm lý trước khi trả lời.


1
vấn đề là khi tôi khởi động máy chủ, có một số như 50 máy khách kết nối với máy chủ của tôi. Tôi đã triển khai một loại tín hiệu chờ khi chấp nhận một ứng dụng khách .. đại loại như while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); gia sư ++; } client = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... và Program.waitToFinishAtClient được sửa đổi trong các chủ đề có chứa các client
Alex

Điều này có thể "chờ đợi" là vấn đề?
Alex

1
tôi có nên để nó được không? không chờ đợi ?
Alex

1
Tôi nghĩ rằng Chờ đợi là vấn đề. Tôi không biết đủ mã của bạn để chắc chắn, nhưng điều đó có vẻ chắc chắn. Chỉ cần tò mò về việc bạn xây dựng dịch vụ của riêng bạn "con đường khó" hoặc nếu bạn đang sử dụng WCF hoặc thậm chí lập từ xa cho điều này ...
David

Dựa trên một chút mã ở đây, tôi thấy có vẻ như vấn đề "chờ đợi" có thể tránh được nếu nó nằm trong một chuỗi riêng biệt cho mỗi kết nối. Chỉ trong trường hợp phỏng đoán đó là đúng, đây là một ví dụ về Dịch vụ TCP đa luồng với đa luồng có thể giúp bạn: switchhonthecode.com/tutorials/…
David

180

Tôi gặp lỗi này khi gọi một dịch vụ web. Vấn đề cũng liên quan đến an ninh cấp độ giao thông. Tôi có thể gọi dịch vụ web thông qua một dự án trang web, nhưng khi sử dụng lại mã tương tự trong một dự án thử nghiệm, tôi sẽ nhận được một WebException chứa thông báo này. Thêm dòng sau trước khi thực hiện cuộc gọi đã giải quyết được sự cố:

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

Biên tập

System.Net.ServicePointManager.SecurityProtocol - Thuộc tính này chọn phiên bản của giao thức Lớp cổng bảo mật (SSL) hoặc Bảo mật lớp truyền tải (TLS) để sử dụng cho các kết nối mới chỉ sử dụng lược đồ Giao thức truyền siêu văn bản an toàn (HTTPS); kết nối hiện tại không thay đổi.

Tôi tin rằng SecurityProtocolcấu hình rất quan trọng trong quá trình bắt tay TLS khi chọn phiên bản giao thức.

Bắt tay TLS - Giao thức này được sử dụng để trao đổi tất cả thông tin được yêu cầu bởi cả hai bên để trao đổi dữ liệu ứng dụng thực tế bằng TLS.

ClientHello - Ứng dụng khách gửi thông báo ClientHello chỉ định phiên bản giao thức TLS cao nhất mà nó hỗ trợ ...

ServerHello - Máy chủ phản hồi bằng thông báo ServerHello, chứa phiên bản giao thức đã chọn ... Phiên bản giao thức đã chọn phải là phiên bản cao nhất mà cả máy khách và máy chủ đều hỗ trợ. Ví dụ: nếu máy khách hỗ trợ TLS phiên bản 1.1 và máy chủ hỗ trợ phiên bản 1.2 thì nên chọn phiên bản 1.1; phiên bản 1.2 không nên được chọn.


8
điều này đã cứu tôi! cảm ơn anh bạn. trong trình gỡ lỗi của tôi, tôi đang cố gắng gọi một dịch vụ https trong khi thử nghiệm và gặp sự cố mà OP đang gặp phải.
Blair Holmes

6
Chúng ta có biết thêm về cách thức / tại sao điều này hoạt động không? Tôi đã gặp khó khăn với cuộc gọi PostAsync và điều này dường như cũng sửa được lỗi của tôi. Rất vui vì nó hoạt động, nhưng tôi cũng muốn biết tại sao.
Kevin Matlock

1
@HansVonn Cảm ơn vì điều này! Đã tiết kiệm cho tôi rất nhiều thời gian - Về lý do tại sao nó hoạt động Nó chỉ giới hạn phiên bản TLS bạn đang sử dụng khi kết nối.
bối rối và bối rối

1
Không thể tin rằng điều này đã làm cho tôi một lần nữa! Cảm ơn
Sergio A.

2
CẢM ƠN BẠN! Điều này khiến tôi phát điên.
mknopf 19/02/19

34

Tình huống cụ thể của tôi là dịch vụ ứng dụng Azure có phiên bản TLS tối thiểu được thay đổi thành 1.2

Tôi không biết liệu đó có phải là mặc định từ bây giờ hay không, nhưng việc thay đổi nó trở lại 1.0 đã làm cho nó hoạt động.

Bạn có thể truy cập cài đặt bên trong "Cài đặt SSL".


7
Oh my god CẢM ƠN CÁC BẠN NHIỀU! Tôi đã bị mắc kẹt về vấn đề này quá lâu và tôi đã kiểm tra cài đặt SSL của ứng dụng web và mức tối thiểu được đặt thành 1,2 thay vì 1,0. Khi tôi thay đổi nó trở lại 1.0 và khởi động lại ứng dụng web, nó đã hoạt động! Cảm ơn bạn rất nhiều!
Mason

1
Cảm ơn rất nhiều, @ hugo-hilário, thật tuyệt vời là nó cũng hiệu quả với tôi! Làm thế quái nào mà bạn xoay sở để tìm ra một giải pháp phức tạp như vậy! : D
hosjay

@hosjay nó là một địa ngục đối với tôi là tốt :)
Hugo Hilário

3
Đã cứu người bạn đời trong ngày của tôi!
Nitesh

Tôi gặp sự cố này đối với Chức năng Azure v2 của mình
Pieter Heemeryck,

17

Không chắc bản sửa lỗi nào trong các bài đăng blog này đã giúp ích, nhưng một trong số họ đã sắp xếp vấn đề này cho tôi ...

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

Mẹo đã giúp tôi là bỏ sử dụng WebRequest và thay vào đó sử dụng HttpWebRequest. HttpWebRequest cho phép tôi chơi với 3 cài đặt quan trọng:

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

  • BƯỚC 1: Tắt KeepAlive
  • BƯỚC 2: Đặt ProtocolVersion thành Phiên bản10
  • BƯỚC 3: Giới hạn số lượng điểm dịch vụ

1
Câu trả lời này là những gì đã giải quyết vấn đề tương tự này cho tôi. Tôi tắt 'Keep Alive' trong phần Http Tiêu đề phản hồi trong IIS7
drzounds

Tôi nên thêm rằng tôi cũng phải thêm mã này vào Reference.cs cho dịch vụ web đang có hành vi đó. ghi đè được bảo vệ System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = false; trả về webRequest; }
drzounds

11

Các cuộc gọi đến dịch vụ HTTPS từ một trong các máy chủ của chúng tôi cũng gặp phải ngoại lệ " Không thể đọc dữ liệu từ kết nối truyền tải: Kết nối hiện có đã bị buộc đóng ". Tuy nhiên, dịch vụ HTTP hoạt động tốt. Đã sử dụng Wireshark để thấy rằng đó là Lỗi bắt tay TLS. Cuối cùng là bộ mật mã trên máy chủ cần được cập nhật.


Đây là những gì đã xảy ra với tôi. A đã gửi một chứng chỉ đã hết hạn cho một hình nón SSL. A gia hạn chứng chỉ và hoạt động.
Guilherme de Jesus Santos

8

Theo "Hans Vonn" trả lời.

Thêm dòng sau trước khi thực hiện cuộc gọi đã giải quyết được sự cố:

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

Sau khi thêm giao thức Bảo mật và hoạt động tốt nhưng tôi phải thêm trước mỗi lệnh gọi API không lành mạnh. Tôi chỉ cần nâng cấp phiên bản khung .net ít nhất là 4.6 và hoạt động như mong đợi mà không yêu cầu thêm trước mỗi lệnh gọi API.


1
Cảm ơn rât nhiều. bạn đã làm nên ngày của tôi. Nó có thể hữu ích cho một số người nếu tôi đề cập rằng trước đó tôi cũng đã thử nghiệm hủy kích hoạt tường lửa và thêm ServicePointManager.ServerCertificateValidationCallback nhưng không hoạt động.
Tekin

5

Điều này sẽ không giúp ích cho các vấn đề liên tục, nhưng có thể hữu ích cho những người khác gặp vấn đề tương tự.

Tôi đã sao chép một máy ảo và khởi động nó trên một mạng khác với địa chỉ IP mới nhưng không thay đổi các ràng buộc trong IIS. Fiddler đã cho tôi biết "Không thể đọc dữ liệu từ kết nối truyền tải: Một kết nối hiện có đã bị máy chủ từ xa buộc đóng" và IE cho tôi biết "Bật TLS 1.0, TLS 1.1 và TLS 1.2 trong Cài đặt nâng cao". Thay đổi ràng buộc thành địa chỉ IP mới đã giải quyết được vấn đề đó cho tôi.


2

Vì một số lý do, kết nối với máy chủ đã bị mất. Có thể máy chủ đã đóng kết nối một cách rõ ràng hoặc một lỗi trên máy chủ khiến nó bị đóng đột ngột. Hoặc một cái gì đó giữa máy khách và máy chủ (bộ chuyển mạch hoặc bộ định tuyến) làm rớt kết nối.

Đó có thể là mã máy chủ gây ra sự cố và có thể không phải vậy. Nếu bạn có quyền truy cập vào mã máy chủ, bạn có thể đặt một số gỡ lỗi vào đó để cho bạn biết khi nào các kết nối máy khách bị đóng. Điều đó có thể cung cấp cho bạn một số dấu hiệu về thời điểm và lý do tại sao kết nối bị ngắt.

Trên máy khách, bạn phải viết mã của mình để tính đến khả năng máy chủ bị lỗi bất cứ lúc nào. Đó là lý do: các kết nối mạng vốn không đáng tin cậy.


2

Điều này đã giải quyết vấn đề của tôi. Tôi đã thêm dòng này trước khi yêu cầu được thực hiện:

System.Net.ServicePointManager.Expect100Continue = false;

Có vẻ như có một proxy trong cách máy chủ không hỗ trợ hành vi 100 tiếp tục.


1

Tôi nhận được vấn đề đó trong quá khứ. Tôi đang sử dụng PostgreSQL và khi tôi chạy chương trình của mình, đôi khi nó kết nối và đôi khi nó báo lỗi như vậy.

Khi tôi thử nghiệm với mã của mình, tôi đặt mã Kết nối của mình ở dòng đầu tiên bên dưới Biểu mẫu công khai. Đây là một ví dụ:

TRƯỚC:

    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());
        }

HIỆN NAY:

    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!

        }

Mình nghĩ chương trình phải đọc trước kết nối trước khi làm gì, mình không biết thì sửa cho mình nếu sai. Nhưng theo nghiên cứu của tôi, đó không phải là vấn đề về mã - nó thực sự là từ chính chiếc máy.

Chúc bạn mã hóa vui vẻ!


1
System.Net.ServicePointManager.Expect100Continue = false;

Sự cố này đôi khi xảy ra do máy chủ proxy được triển khai trên máy chủ web. Để vượt qua máy chủ proxy bằng cách đặt dòng này trước khi gọi dịch vụ gửi.


0

Tôi đã có một ứng dụng của Bên thứ ba (Fiddler) đang chạy để thử và xem các yêu cầu được gửi đi. Đóng ứng dụng này đã sửa nó cho tôi


0

Chúng tôi đã gặp phải một vấn đề tương tự, trong đó trang web của khách hàng đang cố gắng kết nối với dịch vụ API Web của chúng tôi và nhận được thông báo tương tự. Điều này bắt đầu xảy ra hoàn toàn bất thường khi không có thay đổi mã hoặc bản cập nhật Windows trên máy chủ nơi IIS đang chạy.

Trong trường hợp của chúng tôi, hóa ra trang web đang gọi đang sử dụng phiên bản .Net chỉ hỗ trợ TLS 1.0 và vì lý do nào đó, máy chủ nơi IIS của chúng tôi đang chạy có vẻ như đã ngừng chấp nhận các cuộc gọi TLS 1.0. Để chẩn đoán rằng chúng tôi phải bật TLS một cách rõ ràng thông qua sổ đăng ký trên máy chủ của IIS và sau đó khởi động lại máy chủ đó. Đây là các khóa 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

Câu trả lời của tôi cho một câu hỏi khác ở đây có tập lệnh powershell này mà chúng tôi đã sử dụng để thêm các mục:

LƯU Ý: Kích hoạt các giao thức bảo mật cũ không phải là một ý tưởng hay, câu trả lời đúng trong trường hợp của chúng tôi là yêu cầu trang web khách cập nhật mã của nó để sử dụng TLS 1.2, nhưng các mục đăng ký ở trên có thể giúp chẩn đoán sự cố ngay từ đầu.


0

Lý do điều này xảy ra với tôi là tôi có sự phụ thuộc đệ quy vào nhà cung cấp DI của mình. Trong trường hợp của tôi, tôi đã có:

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

Khắc phục là chỉ xóa đăng ký dịch vụ có phạm vi thứ hai

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

0

Nếu bạn có chứng chỉ https trên miền, hãy đảm bảo rằng bạn có liên kết https với tên miền trong IIS. Trong IIS -> Chọn miền của bạn -> Nhấp vào Bindings Trang web Bindings Window mở ra. Thêm một ràng buộc cho https.


0

Gặp sự cố tương tự và gặp các lỗi sau tùy thuộc vào ứng dụng tôi đã sử dụng và liệu chúng tôi có vượt qua tường lửa / bộ cân bằng tải hay không:

Không bắt tay HTTPS với [blah] (cho # 136). System.IO.IOException Không thể đọc dữ liệu từ kết nối truyền tải: Một kết nối hiện có đã bị buộc đóng bởi máy chủ từ xa

ReadResponse () không thành công: Máy chủ không trả lại phản hồi đầy đủ cho yêu cầu này. Máy chủ trả về 0 byte.

Vấn đề hóa ra là Chứng chỉ máy chủ SSL bị thiếu và không được cài đặt trên một vài máy chủ.


0

Hãy thử kiểm tra xem bạn có thể thiết lập bắt tay ngay từ đầu hay không. Tôi đã gặp sự cố này trước đây khi tải lên một tệp và tôi chỉ phát hiện ra rằng vấn đề là tuyến không tồn tại khi tôi xóa tệp tải lên và kiểm tra xem nó có thể đăng nhập được không với các thông số.



0

Đối với tôi, đó là một vấn đề mà trong ràng buộc IIS nó có địa chỉ IP của máy chủ web. Tôi đã thay đổi nó để sử dụng tất cả các IP chưa được chỉ định và ứng dụng của tôi bắt đầu hoạt động.


0

Tôi đã gặp lỗi với python clr khi chạy truy vấn mdx tới các dịch vụ phân tích của Microsoft bằng cách sử dụng adomd

Tôi đã giải quyết nó với sự trợ giúp của Hans Vonn và đây là phiên bản python :

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

0

Đối với những người có thể tìm thấy điều này sau đó, sau phiên bản .NET 4.6, tôi cũng gặp phải sự cố này.

Đảm bảo rằng bạn kiểm tra tệp web.config của mình để tìm các dòng sau:

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

Nếu bạn đang chạy 4.6.x hoặc phiên bản .NET cao hơn trên máy chủ, hãy đảm bảo rằng bạn điều chỉnh các giá trị targetFramework này để phù hợp với phiên bản của khung trên máy chủ của bạn. Nếu các phiên bản của bạn đọc ít hơn 4.6.x, thì tôi khuyên bạn nên nâng cấp .NET và sử dụng phiên bản mới hơn trừ khi mã của bạn phụ thuộc vào phiên bản cũ hơn (trong trường hợp đó, bạn nên xem xét cập nhật nó).

Tôi đã thay đổi targetFrameworks thành 4.7.2 và sự cố đã biến mất:

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

Các khung công tác mới hơn sẽ giải quyết vấn đề này bằng cách sử dụng giao thức tốt nhất hiện có và chặn những giao thức không an toàn hoặc lỗi thời. Nếu dịch vụ từ xa mà bạn đang cố gắng kết nối hoặc gọi gặp lỗi này, có thể là chúng không hỗ trợ các giao thức cũ nữa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.