2016-06-08 53 views
0

我想要實現讀/寫一個UNIX插座此bash的命令的功能:如何以正確的方式讀取/寫入UNIX套接字?

echo „READ <a command>「 | nc -U /tmp/socket 

此命令會生成以下的輸出:

Click::ControlSocket/1.3 
200 Read handler 'debug_handler.ping' OK 
DATA 0 

我現在的C/C++實現看起來像這樣:

myprogram.hh

class Myprogram { 
public: 
    Myprogram(int argc, char** argv); 
    ~Myprogram() { }; 
private: 
    foo(); 
    int sockfd; 
    int len; 
    sockaddr_un address; 
}; 

myprogram.cc

Myprogram::foo() { 
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 
    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, "/tmp/socket"); 
    len = sizeof(address); 

    if(connect(sockfd, (sockaddr*)&address, len) == -1) 
     return; 

    std::string args = "READ <a command>"; 

    if (write(sockfd, args.c_str(), sizeof(args.c_str())) == -1){ 
     std::cout << "Error" << std::endl; 
     return; 
    } 

    int n; 
    char ret_value[200]; 
    do { 
     n = read(sockfd, ret_value, 200); 
     std::cout << std::string(ret_value) << std::endl; 
     std::cout << "n=" << std::to_string(n) << std::endl; 
     *ret_value+= n; 
    } while (n > 0); 

    close(sockfd); 
} 

我只得到這樣的輸出:

Click::ControlSocket/1.3 
n=26 

下一個read()調用不返回,程序等待。 我已經嘗試了很多閱讀套接字,所有的結果都一樣, 所以如果有人能夠給我一個提示我做錯了什麼,那將會很棒。

+0

'的sizeof(args.c_str())'是4或8。 – immibis

+5

'的sizeof(args.c_str())'應該是'args.size()'。 –

+3

C/C++不是一種語言。如果你認爲'class'是一個關鍵字,那麼你正在編寫C++。 –

回答

2
std::string args = "READ <a command>"; 

服務器正在等待一個新行(回波添加一個默認情況下),所以:

std::string args = "READ <a command>\n"; 

另外

char ret_value[200]; 
do { 
    n = read(sockfd, ret_value, 200); 

應該更像

const size_t buflen = 200; 
char ret_value[buflen+1]; 
do { 
    n = read(sockfd, ret_value, buflen); 
    if (n < 0) 
     // error 
    else 
     ret_value[n] = 0; 

和這條線

*ret_value+= n; 

似乎不清楚 - 你正在增加ret_value的第一個字節n爲什麼?

+1

我還將sizeof(args.c_str())更改爲args.size(),如@πάνταῥεῖ所述。但所有提示都很有幫助,謝謝。 – S1J0

1

嘗試更多的東西是這樣的:

Myprogram::foo() { 
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0); 
    if (sockfd == -1) { 
     std::cout << "Error" << std::endl; 
     return; 
    } 

    address.sun_family = AF_UNIX; 
    strcpy(address.sun_path, "/tmp/socket"); 

    if (connect(sockfd, (sockaddr*)&address, sizeof(address)) == -1) { 
     std::cout << "Error" << std::endl; 
     close(sockfd); 
     return; 
    } 

    std::string args = "READ <a command>\n"; 
    if (write(sockfd, args.c_str(), args.size())) == -1) { 
     std::cout << "Error" << std::endl; 
     close(sockfd); 
     return; 
    } 

    int n; 
    char ret_value[200]; 
    do { 
     n = read(sockfd, ret_value, sizeof(ret_value)); 
     if (n < 0) { 
      std::cout << "Error" << std::endl; 
      break; 
     } 

     if (n == 0) { 
      break; 
     } 

     std::cout.write(ret_value, n) << std::endl; 
     std::cout << "n=" << n << std::endl; 
    } while (true); 

    close(sockfd); 
} 

當然,如果你真的想要的輸出出現就像當初不是沒有自己的字符添加到cout(除了可能在錯誤的情況下):

int n; 
char ret_value[200]; 
do { 
    n = read(sockfd, ret_value, sizeof(ret_value)); 
    if (n < 0) { 
     //std::cout << "Error" << std::endl; 
     break; 
    } 

    if (n == 0) { 
     break; 
    } 

    std::cout.write(ret_value, n); 
} while (true); 
+0

這是一個很好的解決方案,謝謝。但是,如果所有行都被讀取了,讀取函數將不會返回並且程序等待,但仍然存在問題。 – S1J0