2011-02-02 31 views
6

Tôi cần tạo một ứng dụng linux có thể quét mạng không dây, đặt kết quả vào một cấu trúc và gửi nó bằng cách nào đó, ứng dụng chính sẽ sử dụng dữ liệu. Ý tưởng ban đầu của tôi là tạo một đường ống trong ứng dụng chính, ngã ba và bắt đầu một quá trình khác bằng execl, có thể ghi vào đường ống. Một cái gì đó như thế này:Làm thế nào để trao đổi dữ liệu nhị phân giữa các quy trình trong Linux

pid_t pid = NULL; 
int pipefd[2]; 
FILE* output; 
char line[256]; 

pipe(pipefd); 
pid = fork(); 
if (pid == 0) 
{ 
// Child 
    close(pipefd[0]); 
    dup2(pipefd[1], STDOUT_FILENO); 
    dup2(pipefd[1], STDERR_FILENO); 
    execl("/sbin/wifiscan", "/sbin/wifiscan", (char*) NULL); 
} 

//Only parent gets here. Listen to what the wifi scan says 
close(pipefd[1]); 
output = fdopen(pipefd[0], "r"); 

while(fgets(line, sizeof(line), output)) 
{ 
//Here we can listen to what wifiscan sends to its standard output 
} 

Tuy nhiên, điều này sẽ không hoạt động với dữ liệu nhị phân, nếu nhị phân 0 xuất hiện ở đầu ra. Vì vậy, tôi có thể định dạng đầu ra của ứng dụng wifiscan thành văn bản, gửi nó vào đường ống và phân tích cú pháp trong ứng dụng chính hoặc làm theo cách thông minh hơn mà tôi chưa biết.

Các phương tiện khác để trao đổi dữ liệu đáng tin cậy giữa các quy trình trong Linux là gì?

Trả lời

7

tôi nghi ngờ những gì xảy ra là fgets() được đọc ký tự NUL đúng, nhưng bạn đang giải thích một trong những đầu tiên như là sự kết thúc của dòng đã được đọc. Đó là khó khăn bởi vì fgets() là dành cho đầu vào văn bản, và nó sử dụng '\ 0' như một sentinel, không trả về số lượng ký tự đọc. Ngay cả khi bạn biết mỗi dòng sẽ bị \n chấm dứt, có khả năng là dữ liệu nhị phân thô được nhúng trong một dòng sẽ bao gồm một số \n. Vì vậy, chuyển sang fread(), có nghĩa là cho nhị phân. Bạn có thể đặt kích thước tin nhắn có độ dài cố định (ví dụ 2 byte, 4 byte) ở phía trước mỗi thư để phía bên kia có thể đọc đầu tiên sau đó thực hiện fread() cho kích thước thư chính xác, tránh các vấn đề lộn xộn .

Nếu bạn thực sự muốn giữ nó một số lai kỳ lạ của văn bản và nhị phân, bạn có thể thử sử dụng ftell() sau fgets() để tìm hiểu cách thức nhiều hơn nữa dọc theo dòng bạn đang có, và do đó có bao nhiêu nhân vật nên có trong bộ đệm của bạn , nhưng tôi chưa bao giờ thấy một hệ thống nghiêm túc làm điều gì đó để hacky.

Để lưu bản ghi mà không làm điều gì đó không hiệu quả như mã hóa hex mọi ký tự đơn trong dữ liệu nhị phân, bạn chỉ có thể mã hóa (các) ký tự phiền hà. Ví dụ: có thể sử dụng chuỗi thoát chuỗi ký tự C chuỗi, với \0 đại diện cho một số NUL và \\ một đơn \. Mặc dù ít dễ dàng kiểm tra trực quan hơn, nhưng việc lập trình/giải mã các ký tự không thể in dễ dàng hơn bằng cách sử dụng nói số bát phân \NNN. Nếu có nhiều ký tự không thể in được, thì phương pháp tiếp cận uuencode cơ bản-64 - chẳng hạn như được sử dụng trong các tệp đính kèm email MIME - là một mã hóa phù hợp khác nhưng hoàn toàn không thể đọc được.

+1

'ftell()' có thể không hoạt động trên các luồng không thể dò tìm như đường ống. – caf

+0

Tôi đồng ý với việc xây dựng một giao thức cơ bản cho dữ liệu của bạn và sau đó sử dụng 'fread()' thay vì 'fgets()'. Câu trả lời này về [triển khai FIFO] (http://stackoverflow.com/q/2870549/203667) [answer] (http://stackoverflow.com/questions/2870549/fifos-implementation/2871538#2871538) có thể được sử dụng bổ sung vì nó cung cấp một vài ví dụ về cách một giao thức như vậy có thể được xây dựng. – jschmier

+0

fread() hoạt động hoàn hảo. Cảm ơn – Patryk

0

Trao đổi dữ liệu đáng tin cậy? Điều này làm cho tôi suy nghĩ về thư viện 0MQ (ZeroMQ): http://zeromq.org

Có một cái nhìn và tiền thưởng mà quy trình của bạn sẽ có thể nói ngay cả trên máy tính ở xa.

Chào mừng bạn đến với đám mây.

2

Thông thường, một người sẽ sử dụng freadfwrite để trao đổi cấu trúc nhị phân trên các quy trình. Nó hoạt động tốt cho các bản ghi độ dài cố định, và không có vấn đề gì khi gửi null, v.v.

Tôi đã tìm thấy sự nghiệp lâu dài của mình trong hầu hết các ứng dụng, tốt hơn là trao đổi chuỗi ascii, dễ dàng phân tích cú pháp (ví dụ: scanf), thay vì dữ liệu nhị phân. Bằng cách đó các tin nhắn có thể được quan sát và ghi lại, và các quy trình riêng lẻ có thể được kiểm tra bằng cách telnetting và gõ (thường là dán) vào chúng. Nó chỉ làm cho nó dễ dàng hơn để phát triển nếu các lập trình viên chỉ có thể đọc lưu lượng tin nhắn. Tuy nhiên,

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