如何以正确的方式读/写 UNIX 套接字
How to read/write UNIX sockets the right way?
我想实现这个 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() 调用不会返回,程序会等待。我尝试了很多方法来读取套接字,结果都相同,所以如果有人能给我一个提示,我做错了什么,那就太好了。
std::string args = "READ <a command>";
服务器正在等待换行符(echo 默认添加一个换行符),因此:
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 是什么原因?
尝试类似这样的事情:
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);
相关文章:
- 用于通信C++的 UNIX 套接字
- SOCAT,将TCP套接字转发到Unix套接字,将recvmsg()更改为read(),删除辅助数据
- Unix 套接字挂在 recv 上,直到我在任何地方放置/删除断点
- 在 unix 套接字上调用async_connect有意义吗?
- Qt5 有没有办法让QLocalServer监听抽象的Unix套接字
- 使用UNIX套接字C++客户端与Node.js服务器通信的简单示例
- 如何以正确的方式读/写 UNIX 套接字
- 将Unix套接字移植到Windows
- C++ 在基于 UNIX 套接字的客户端程序中 connect() 不会建立与服务器的连接
- Unix 套接字循环
- 在同一 unix 套接字连接中读取元素两次时出错
- 关闭 Unix 套接字时内存损坏
- Unix套接字发送接收客户端到服务器大块数据错误
- 使用unix套接字获取本地ip地址
- 数据报Unix套接字上的ECONNREFUSED
- c++ Unix套接字捕获系统调用
- 通过本地UNIX套接字发送double
- 如何在CGI程序中使用UNIX套接字
- c++ Qt写unix套接字
- 使用UNIX套接字,了解如何在发送数据的同时等待数据