2010-06-10 29 views
5

Câu hỏi ngắn
Cách đúng để xử lý sự kiện Ctrl-C được gửi qua Telnet ở phía máy chủ là gì?Ổ cắm POSIX: Cách phát hiện Ctrl-C được gửi qua Telnet?

Câu hỏi dài
Sau khi gọi recv() trên ổ cắm, tôi muốn xử lý một số trường hợp một cách thích hợp. Một trong số đó là trả về một mã lỗi nhất định khi nhận được Ctrl-C. Cách chính xác để phát hiện điều này là gì? Các công trình sau đây, nhưng nó chỉ có vẻ không đúng:

size_t recv_count; 
static char ctrl_c[5] = {0xff, 0xf4, 0xff, 0xfd, 0x06}; 

recv_count = recv(socket, buffer, buffer_size, 0); 

if (recv_count == sizeof(ctrl_c) && 
    memcmp(buffer, ctrl_c, sizeof(ctrl_c) == 0) 
{ 
    return CTRL_C_RECEIVED; 
} 

Tôi tìm thấy một bình luận trên Ctrl-C trong một phụ lưu ý trong this UNIX Ổ cắm FAQ:

[...] (bằng cách này, out-of-band thường được sử dụng cho ctrl-C đó).

Như tôi đã hiểu, việc nhận dữ liệu ngoài băng được thực hiện bằng cách sử dụng recv() với một cờ nhất định làm thông số cuối cùng. Nhưng khi tôi chờ đợi dữ liệu bằng cách sử dụng recv() như tôi đã làm trong đoạn mã trên, tôi không thể đọc dữ liệu ngoài băng cùng một lúc. Ngoài ra, tôi nhận được một cái gì đó bằng cách sử dụng recv() mà không có cờ oob đó.

+0

Ctrl-D được gửi bằng telnet dưới dạng ký tự^D (0x04) –

Trả lời

2

Đặt ổ cắm thành không chặn bằng fcntl(), sử dụng select() (pselect() trên một số hệ thống) để kiểm tra dữ liệu đến. Đó là cách lấy mẫu điều kiện hiện tại của ổ cắm, tức là liệu nó có dữ liệu để recv() và nếu có thể chấp nhận một gửi(), hoặc có một ngoại lệ. Đừng đơn giản ngồi ở đó.

Lệnh recv() trả về càng nhiều thông tin có sẵn vì kích thước của bộ đệm được cung cấp có thể giữ. Nếu socket đã được cấu hình để nhận dữ liệu ngoài băng tần (tùy chọn socket SO_OOBINLINE) và có dữ liệu OOB chưa đọc, chỉ dữ liệu ngoài dải được trả về. Gọi ioctl() SIOCATMARK để xác định xem có thêm dữ liệu ngoài băng nào không đọc được không.

Khi bạn nhận được dữ liệu OOB, bạn không thể recv() kết thúc phần cuối của gói OOB trong một cuộc gọi recv() duy nhất, do đó, đó là chứng minh goof trong vấn đề đó.

Tôi không biết những gì được coi là thực hành tốt nhất, nhưng ý tưởng lấy ctrl-c trước dữ liệu ổ cắm đã được đệm khác là một tốt nhất.

+0

Thực ra, tôi đang viết thư viện để sử dụng trong nhà cung cấp các chức năng tiện lợi cho ổ cắm (đã có một số fcntl() và chọn() trong đó), do đó, vấn đề này không cụ thể đối với việc triển khai ứng dụng cụ thể, mà đúng hơn là "một thứ khác mà thư viện tuyệt vời của tôi có thể trợ giúp". Tôi đã hy vọng nắm bắt các sự kiện như một ctrl-c mà không có dữ liệu OOB để giữ cho nó đơn giản. Tôi đồng ý không chỉ ngồi trong recv() và chờ và thư viện của tôi hỗ trợ chế độ chặn và không chặn, nhưng sẽ rất tuyệt khi thực hiện công cụ này một lần và nó hoạt động mọi lúc (tm). Dù sao, cảm ơn câu trả lời! –

+0

http://linux.softpedia.com/get/Programming/Libraries/sWrapper-35278.shtml –

+0

Liên kết trên là một ví dụ về một số nỗ lực tương tự để làm cho ổ cắm ít tham gia hơn. IMO cách tiếp cận có liên quan hơn cho phép bạn 'tinh chỉnh các thiết lập' theo nhu cầu chính xác của bạn. 'nhu cầu chính xác' có thể khó thực hiện mà không cần thêm nhiều tùy chọn phức tạp trong mã của bạn. Điều này làm hỏng nỗ lực của bạn. –

Các vấn đề liên quan