2012-06-26 8 views
6

tôi đang học cách sử dụng SO_SNDTIMEOSO_RCVTIMEO để kiểm tra thời gian chờ. Rất dễ sử dụng với đọc ổ cắm. Nhưng khi tôi muốn kiểm tra ghi thời gian chờ, nó luôn trở lại thành công. Dưới đây là những gì tôi đã làm: (tất cả trong chế độ chặn)làm thế nào để mô phỏng trường hợp bất thường cho lập trình socket/tcp trong linux, chẳng hạn như chấm dứt một bên của kết nối?

  1. gần client đọc ổ cắm và thoát trước khi máy chủ bắt đầu ghi
  2. chấm dứt khách hàng trước khi máy chủ bắt đầu ghi
  3. tháo cáp máy chủ sau chấp nhận nhưng trước viết

tốt, có vẻ như tất cả các trường hợp này viết vừa trở lại thành công. Tôi nghĩ lý do nên là cổng là tài nguyên được quản lý bởi os, và ở phía máy khách, sau khi chương trình biến mất, kết nối tcp vẫn hiển thị trạng thái FIN_WAIT2.

vậy, liệu có cách nào thuận tiện để mô phỏng một số trường hợp mà ghi có thể nhận được lỗi như EPIPE, EAGAIN?

Trả lời

5

Cách nhận lỗi EAGAIN?
Để nhận lỗi EAGAIN, bạn cần phải sử dụng Ổ cắm không chặn. Với các ổ cắm không chặn, bạn cần viết một lượng lớn dữ liệu (và dừng nhận dữ liệu ở phía ngang hàng), để bộ đệm TCP bên trong của bạn được lấp đầy và trả về lỗi này.

Làm cách nào để nhận lỗi EPIPE?
Để nhận lỗi EPIPE, bạn cần gửi số lượng lớn dữ liệu sau khi đóng socket ở phía bên kia. Bạn có thể nhận thêm thông tin về lỗi EPIPE từ SO Link này. Tôi đã hỏi một câu hỏi về lỗi ống hỏng trong liên kết được cung cấp và câu trả lời được chấp nhận đưa ra một lời giải thích chi tiết. Điều quan trọng cần lưu ý là để nhận được lỗi EPIPE, bạn nên thiết lập tham số cờ gửi tới MSG_NOSIGNAL. Nếu không có điều đó, một gửi bất thường có thể tạo ra tín hiệu SIGPIPE.

bổ sung Note
Xin lưu ý rằng rất khó để mô phỏng một thất bại ghi, như TCP thường lưu trữ các dữ liệu mà bạn đang cố gắng để viết vào đó là bộ đệm bên trong. Vì vậy, nếu bộ đệm trong có đủ không gian, thì bạn sẽ không gặp lỗi ngay lập tức. Cách tốt nhất là cố gắng viết một lượng lớn dữ liệu.Bạn cũng có thể thử đặt kích thước bộ đệm nhỏ hơn để gửi bằng cách sử dụng chức năng setsockopt với tùy chọn SO_SNDBUF

+0

cảm ơn thông tin của bạn và tôi sẽ thử. Đối với ** đọc **, tôi thực sự có EAGAIN và EWOULDBLOCK trong chế độ Chặn khi hết thời gian chờ. Tôi chỉ giả sử nó hoạt động giống nhau khi ** viết ** thời gian chờ. – xgwang

1

Bạn có thể đặt kích thước bộ đệm nhận thực sự nhỏ ở một bên và gửi bộ đệm lớn lên một mặt khác. Hoặc ở một bên đặt bộ đệm gửi nhỏ và cố gắng gửi một tin nhắn lớn.

Nếu không, kiểm tra phổ biến nhất (tôi nghĩ) là để máy chủ và ứng dụng khách nói chuyện một lúc, sau đó tháo cáp mạng.

5

Bạn có thể mô phỏng lỗi bằng cách sử dụng fault injection. Ví dụ: libfiu là thư viện tiêm lỗi đi kèm với dự án mẫu cho phép bạn mô phỏng lỗi từ các chức năng POSIX. Về cơ bản nó sử dụng LD_PRELOAD để tiêm một wrapper xung quanh các cuộc gọi hệ thống thông thường (bao gồm write), và sau đó trình bao bọc có thể được cấu hình để chuyển sang cuộc gọi hệ thống thực hoặc trả lại bất kỳ lỗi nào bạn thích.

+0

cảm ơn. Nó có lẽ không phải những gì tôi đang tìm kiếm, nhưng lỗi tiêm dường như thú vị. Tôi nghĩ rằng tôi có thể tìm hiểu nó để cải thiện phạm vi mã. – xgwang