Các lý do chính thức cho Phần mềm đã gây ra hủy bỏ kết nối: lỗi ghi ổ cắm


157

Đưa ra đoạn trích dấu vết ngăn xếp này

Nguyên nhân do: java.net.SocketException: Phần mềm gây ra hủy kết nối: lỗi ghi socket
 tại java.net.SocketOutputStream.socketWrite0 (Phương thức gốc)

Tôi đã cố gắng trả lời các câu hỏi sau đây:

  1. Mã nào đang ném ngoại lệ này? (JVM? / Tomcat? / Mã của tôi?)
  2. Điều gì gây ra ngoại lệ này được ném?

Về # 1:

Nguồn JVM của Sun không chứa thông báo chính xác này, nhưng tôi nghĩ rằng văn bản Phần mềm gây ra hủy bỏ kết nối: lỗi ghi socket là từ bản triển khai gốc của SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

Về # 2

Tôi đoán là nó xảy ra khi máy khách đã chấm dứt kết nối, trước khi nhận được phản hồi đầy đủ (ví dụ: đã gửi yêu cầu, nhưng trước khi nhận được phản hồi đầy đủ, nó đã bị đóng / chấm dứt / ngoại tuyến)

Câu hỏi:

  1. Các giả định trên có đúng không (# 1 và # 2)?
  2. Điều này có thể được phân biệt với tình huống: "không thể ghi vào máy khách, do lỗi mạng ở phía máy chủ " không? hoặc sẽ làm cho thông báo lỗi tương tự?
  3. Và quan trọng nhất: Có tài liệu chính thức (ví dụ từ Mặt trời) nêu rõ những điều trên không?

Tôi cần phải có một bằng chứng rằng dấu vết ngăn xếp này là "lỗi" của máy khách socket và không có gì mà máy chủ có thể làm để tránh nó. (ngoại trừ việc bắt ngoại lệ hoặc sử dụng SunOVM SocketOutputStream không phải Sun, mặc dù cả hai đều không thực sự tránh thực tế máy khách đã chấm dứt)


Tôi gặp vấn đề này khi hủy tải xuống với Firefox
koppor

Này Eran Tôi cũng nhận được ngoại lệ này trong khi gửi / viết ( outs.write(audioBytes);) byte[]vào OutputStream. Khi âm thanh bị méo và trong khi phát nếu người dùng nhấp vào bất kỳ menu nào khác (gửi yêu cầu máy chủ), tôi cũng gặp lỗi tương tự trên bảng điều khiển. Vì vậy, nó có an toàn để bỏ qua ngoại lệ này?
Amogh

1
@Amogh - Có vẻ như vậy, vâng. Về cơ bản từ những gì các câu trả lời mô tả, đây là một lỗi cụ thể của Windows, nhưng tôi cho rằng trên Linux, bạn sẽ có cùng một ngoại lệ chỉ với một từ ngữ khác ... (Hiểu về thuật ngữ giáo dân của tôi về cơ bản là do điều này gây ra khi bạn gửi thông qua một ổ cắm đến một vị trí xa X và X bị ngắt kết nối ở giữa, nhưng tôi chắc chắn đó không phải là cách chính xác nhất để mô tả nó)
Eran Medan

1
Đối với tôi điều này xảy ra khi máy chủ cơ sở dữ liệu được khởi động lại và ứng dụng vẫn đang cố truy vấn bằng các kết nối đã mở trước đó. Không chắc chắn tại sao những người sói này không được làm mới vì chúng tôi đang sử dụng nhóm dựa trên DBCP. Nhưng khởi động lại ứng dụng đã khắc phục vấn đề.
Kshitiz Sharma

Câu trả lời:


55

Lỗi này có thể xảy ra khi hệ thống mạng cục bộ hủy kết nối, chẳng hạn như khi WinSock đóng kết nối đã thiết lập sau khi truyền lại dữ liệu không thành công (người nhận không bao giờ thừa nhận dữ liệu được gửi trên ổ cắm dữ liệu).

Xem bài viết MSDN này . Xem thêm Một số thông tin về 'Phần mềm gây ra hủy bỏ kết nối' .



3
@MatGessel Bài báo đó chỉ lặp lại sự nhầm lẫn, và thêm một số của riêng mình. WSAECONNABORTED là mã lỗi Winsock, do đó không thể có một lời giải thích Berkeley cho nó. Tình huống được mô tả về máy chủ HTTP sẽ tạo ra ECONNRESET, chứ không phải WSAECONNABORTED.
Hầu tước Lorne

@EJP, tôi cũng nhận được ngoại lệ này trong khi gửi / ghi (outs.write (audioBytes);) byte [] vào OutputStream. Khi âm thanh bị méo và trong khi phát nếu người dùng nhấp vào bất kỳ menu nào khác (gửi yêu cầu máy chủ), tôi cũng gặp lỗi tương tự trên bảng điều khiển. Vì vậy, nó có an toàn để bỏ qua ngoại lệ này?
Amogh

1
@rustyx Cả ba nguồn được trích dẫn ở đây đều nói rằng nó được tạo ra bởi các lỗi ACK. Nếu bạn có một nguồn cho yêu cầu của riêng bạn xin vui lòng trích dẫn nó.
Hầu tước Lorne

2
Đây không phải là một câu trả lời thực sự vì nó không cung cấp cho bạn thông tin để theo đuổi vấn đề hơn nữa. Câu trả lời ở đây về cơ bản là "một cái gì đó xấu đã xảy ra trên mạng". Sẽ rất hữu ích để hiểu những gì các bản ghi và hoạt động khác có thể cho phép tôi xác định chính xác vấn đề tiềm ẩn.
Derek Bennett

11

java.net.SocketExceptionđược ném khi có lỗi tạo hoặc truy cập vào một ổ cắm (chẳng hạn như TCP ). Điều này thường có thể được gây ra khi máy chủ đã chấm dứt kết nối (mà không đóng đúng cách), vì vậy trước khi nhận được phản hồi đầy đủ. Trong hầu hết các trường hợp, điều này có thể do sự cố hết thời gian (ví dụ: phản hồi mất quá nhiều thời gian hoặc máy chủ bị quá tải với các yêu cầu) hoặc máy khách đã gửi SYN, nhưng nó không nhận được ACK (xác nhận chấm dứt kết nối) . Đối với các vấn đề thời gian chờ, bạn có thể xem xét tăng giá trị thời gian chờ.

Ngoại lệ socket thường đi kèm với thông báo chi tiết được chỉ định về vấn đề này.

Ví dụ về tin nhắn chi tiết:

  • Phần mềm gây ra hủy bỏ kết nối: recv không thành công.

    Lỗi cho thấy nỗ lực gửi tin nhắn và kết nối đã bị máy chủ của bạn hủy bỏ. Nếu điều này xảy ra trong khi kết nối với cơ sở dữ liệu, điều này có thể liên quan đến việc sử dụng trình điều khiển JDBC của Trình kết nối / J không tương thích .

    Giải pháp có thể: Đảm bảo bạn đã có thư viện / trình điều khiển thích hợp trong CLASSPATH của mình.

  • Phần mềm gây ra hủy bỏ kết nối: kết nối.

    Điều này có thể xảy ra khi có vấn đề để kết nối với điều khiển từ xa. Ví dụ do trình kiểm tra vi rút từ chối các yêu cầu thư từ xa .

    Giải pháp có thể: Kiểm tra dịch vụ quét Virus xem nó có chặn cổng cho các yêu cầu gửi kết nối không.

  • Phần mềm gây ra hủy bỏ kết nối: lỗi ghi socket.

    Giải pháp có thể: Đảm bảo bạn đang viết đúng độ dài byte cho luồng. Vì vậy, hãy kiểm tra lại những gì bạn đang gửi. Xem chủ đề này .

  • Thiết lập lại kết nối theo ngang hàng: lỗi ghi ổ cắm / Kết nối bị hủy bỏ bởi ngang hàng: lỗi ghi ổ cắm

    Ứng dụng không kiểm tra xem kết nối có còn tồn tại đã hết thời gian ở phía máy chủ hay không.

    Giải pháp có thể: Đảm bảo rằng httpClient không có giá trị trước khi đọc từ kết nối. E13222_01

  • Thiết lập lại kết nối bằng ngang hàng.

    Kết nối đã bị chấm dứt bởi máy ngang hàng (máy chủ).

  • Thiết lập lại kết nối.

    Kết nối đã bị chấm dứt bởi máy khách hoặc bị đóng bởi đầu máy chủ của kết nối do yêu cầu với yêu cầu.

    Xem: Điều gì gây ra java.net.SocketException: Thiết lập lại kết nối?


Chỉ có một trong 6 điểm này thực sự trả lời câu hỏi, không chính xác. Một số người khác là không chính xác là tốt. Ứng dụng không thể 'kiểm tra xem kết nối duy trì đã hết thời gian ở phía máy chủ chưa.' Sự HttpClienttồn tại nullkhông thể có thể gây ra a SocketException. Không viết đúng độ dài cho luồng cũng không.
Hầu tước Lorne

9

Tôi đã thấy điều này thường xuyên nhất khi tường lửa công ty trên máy trạm / máy tính xách tay cản trở, nó giết chết kết nối.

ví dụ. Tôi có một quy trình máy chủ và một quy trình khách hàng trên cùng một máy. Máy chủ đang lắng nghe trên tất cả các giao diện (0.0.0.0) và máy khách sẽ thử kết nối với giao diện chung / nhà (lưu ý không phải giao diện loopback 127.0.0.1).

Nếu máy bị ngắt kết nối mạng (ví dụ như tắt wifi) thì kết nối được hình thành. Nếu máy được kết nối với mạng công ty (trực tiếp hoặc vpn) thì kết nối được hình thành.

Tuy nhiên, nếu máy được kết nối với wifi công cộng (hoặc mạng gia đình) thì tường lửa sẽ phá hủy kết nối. Trong tình huống này, kết nối máy khách với giao diện loopback hoạt động tốt, chỉ không với giao diện nhà / công cộng.

Hi vọng điêu nay co ich.


3
Tường lửa ngăn chặn kết nối. Câu hỏi là về việc đặt lại một kết nối hiện có.
Hầu tước Lorne

4

Để chứng minh thành phần nào bị lỗi, tôi sẽ theo dõi giao tiếp TCP / IP bằng cách sử dụng wireshark và xem ai đang đóng cổng một cách chính xác, cũng có thể có thời gian chờ.


Không ai đóng cổng. Hệ điều hành đang hủy bỏ kết nối.
Hầu tước Lorne

@EJP Tôi đã thấy điều này xảy ra khi bị quá tải và hết bộ nhớ. Tôi không chắc chắn đó là HĐH đóng kết nối nhưng JVM phát điên.
Zee

1
@Zee Có một sự khác biệt giữa việc đóng một cổng, được hiển thị dưới dạng FIN trong Wireshark và hủy kết nối, điều này không xảy ra.
Hầu tước Lorne

2

Bạn đã kiểm tra mã nguồn Tomcat nguồn JVM chưa? Điều đó có thể giúp bạn nhiều hơn.

Tôi nghĩ rằng suy nghĩ chung của bạn là tốt. Tôi mong đợi một ConnectExceptionkịch bản mà bạn không thể kết nối. Ở trên có vẻ như nó do khách hàng điều khiển.


3
Có, tôi đã kiểm tra. Các nguồn của Tomcat không chứa bất kỳ hoán vị nào của câu, cảm ơn.
Eran Medan

1
Không, ông đã không kiểm tra nguồn Tomcat nguồn JVM.
Stephen C

Hoặc nếu anh ta đã kiểm tra nguồn JVM, anh ta đã không kiểm tra tất cả nguồn đó.
Stephen C

1
@Ehrann - chuỗi tin nhắn rất có thể trong các nguồn gốc. Nhưng bạn cũng nên kiểm tra nhật ký sự kiện. IMO, sau này có thể sẽ có nhiều thông tin hơn.
Stephen C

6
Chuỗi tin nhắn này đến từ hệ điều hành thực sự.
Hầu tước Lorne

2

Đối với bất kỳ ai sử dụng các chương trình Máy chủ Máy khách đơn giản và gặp phải lỗi này, đó là sự cố của luồng Đầu vào hoặc Đầu ra không được tiết lộ (hoặc đóng cửa sớm).


2
Không, không. Điều đó sẽ tạo ra một rò rỉ ổ cắm, cuối cùng sẽ gây ra cạn kiệt FD.
Hầu tước Lorne

0

Tôi đã phải đối mặt với cùng một vấn đề.
Thông thường Loại lỗi này xảy ra do máy khách đã đóng kết nối và máy chủ vẫn cố ghi trên máy khách đó.
Vì vậy, hãy chắc chắn rằng máy khách của bạn mở kết nối cho đến khi máy chủ hoàn thành với đầu ra của nó.
Và một điều nữa, đừng quên đóng luồng đầu vào và đầu ra.

Hi vọng điêu nay co ich.
Và nếu vẫn phải đối mặt với vấn đề hơn là tóm tắt vấn đề của bạn ở đây một cách chi tiết.


3
@BhavinChhatrola Không, một câu trả lời không chính xác. Tình huống được mô tả tạo ra 'thiết lập lại kết nối theo ngang hàng', không phải lỗi trong câu hỏi.
Hầu tước Lorne

0

Lỗi này xảy ra với tôi khi kiểm tra dịch vụ xà phòng của tôi với ứng dụng khách SoapUI, về cơ bản tôi đã cố gắng nhận được một thông báo rất lớn (> 500kb) và SoapUI đã đóng kết nối khi hết thời gian.

Trên SoapUI, hãy truy cập:

Tệp -> Tùy chọn - Hết thời gian chờ (ms)

... và đặt một giá trị lớn, chẳng hạn như 180000 (3 phút), đây sẽ không phải là cách khắc phục hoàn hảo cho vấn đề của bạn vì thực tế tệp rất lớn, nhưng ít nhất bạn sẽ có phản hồi.


0

Kết nối kín trong một khách hàng khác

Trong trường hợp của tôi, lỗi là:

java.net.SocketException: Software caused connection abort: recv failed

Nó đã nhận được trong nhật thực trong khi gỡ lỗi một ứng dụng java truy cập cơ sở dữ liệu H2. Nguồn gốc của lỗi là ban đầu tôi đã mở cơ sở dữ liệu bằng SQuirreL để kiểm tra tính toàn vẹn theo cách thủ công. Tôi đã sử dụng cờ để kích hoạt nhiều kết nối đến cùng một DB (nghĩa làAUTO_SERVER=TRUE ), vì vậy không có vấn đề gì khi kết nối với DB từ java.

Lỗi xuất hiện khi sau một thời gian - đó là một quá trình java dài-- Tôi quyết định đóng SQuirreL để giải phóng tài nguyên. Có vẻ như SQuirreL là người "sở hữu" cá thể máy chủ DB và nó đã bị tắt với kết nối SQuirreL.

Khởi động lại ứng dụng Java không mang lại lỗi.

cấu hình

  • Windows 7
  • Kepler nhật thực
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

0

Trong trường hợp của tôi, tôi đã phát triển máy khách và phía máy chủ và tôi có ngoại lệ:

Nguyên nhân: lỗi lập luận lỗi; ngoại lệ lồng nhau là: java.net.SocketException: Phần mềm gây ra hủy kết nối: lỗi ghi socket

khi các lớp trong máy khách và máy chủ là khác nhau. Tôi không tải xuống các lớp của máy chủ (Giao diện) trên máy khách, tôi chỉ cần thêm các tệp tương tự trong dự án. Nhưng con đường phải giống hệt nhau. Ví dụ: trong dự án máy chủ tôi có các gói java \ rmi \ services với một số dịch vụ và triển khai dịch vụ, tôi phải tạo cùng một gói trên dự án máy khách. Nếu tôi thay đổi nó bằng java / rmi / server / services chẳng hạn, tôi sẽ có ngoại lệ trên. Cùng một ngoại lệ nếu phiên bản giao diện khác nhau giữa máy khách và máy chủ (ngay cả khi một hàng trống được thêm vào vô tình ... Tôi nghĩ rằng rmi tạo ra một loại hàm băm để kiểm tra phiên bản ... Tôi không biết ... Nếu có thể Cứu giúp ...


-1

Máy chủ của tôi đã ném ngoại lệ này trong 2 ngày và tôi đã giải quyết nó bằng cách di chuyển chức năng ngắt kết nối với:

outputStream.close();
inputStream.close();
Client.close();

Đến cuối của danh sách chủ đề. Nếu nó sẽ giúp bất cứ ai.


-1

Trong tình huống được giải thích bên dưới, phía khách hàng sẽ đưa ra một ngoại lệ như vậy:

Máy chủ được yêu cầu xác thực chứng chỉ ứng dụng khách, nhưng máy khách cung cấp chứng chỉ mà Sử dụng khóa mở rộng không hỗ trợ xác thực ứng dụng khách, vì vậy máy chủ không chấp nhận chứng chỉ của máy khách, sau đó đóng kết nối.


Câu trả lời này không chính xác. Trong trường hợp bạn mô tả một SSLException sẽ bị ném.
Tổng thống James K. Polk

Trên thực tế, nó ném SocketException giống như câu hỏi hiện tại, tôi đã thử nghiệm
xiaoming

-1

phía khách hàng ssl sẽ ném ngoại lệ như vậy trong tình huống dưới đây Tôi đã thử nghiệm) ,:

máy chủ được yêu cầu xác thực chứng chỉ ứng dụng khách, nhưng máy khách cung cấp chứng chỉ mà Sử dụng khóa mở rộng không hỗ trợ khách hàng xác thực.


-3

Tôi đã phải đối mặt với cùng một vấn đề với wireMock trong khi chế nhạo các cuộc gọi API còn lại. Trước đó tôi đã xác định máy chủ như thế này:

WireMockServer wireMockServer = null;

Nhưng nó nên được định nghĩa như dưới đây:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

Điều đó sẽ gây ra một NullPointerException, không phải vấn đề này.
Hầu tước Lorne
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.