【发布时间】:2017-07-22 20:07:48
【问题描述】:
我正在使用 unix 套接字发送和接收信息,但我不完全理解它是如何工作的。基本上,我会发送这样的消息:
int wr_bytes = write(sock, msg.c_str(), msg.length());
并收到这样的消息:
int rd_bytes = read(msgsock, buf, SOCKET_BUFFER_SIZE);
这段代码在数千字节的情况下完美运行,我不明白的是,read 函数如何知道另一部分何时完成发送消息?我尝试阅读read documentation,据我了解,read 将在到达EOF 或SOCKET_BUFFER_SIZE 后返回,对吗?
所以我猜当我将字符串提供给write 函数时,它会在我的内容末尾添加一个EOF,以便read 函数知道何时停止。
我问这个问题是因为,我没有添加任何代码来检查另一部分是否完成发送消息,但是,我收到大消息(数千字节)没有任何问题,为什么会发生这种情况,为什么我只收到部分消息?
这是我用来向 unix 套接字服务器发送消息的完整函数:
string sendSocketMessage(string msg) {
int sock;
struct sockaddr_un server;
char buf[1024];
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
throw runtime_error("opening stream socket");
}
server.sun_family = AF_UNIX;
strcpy(server.sun_path, "socket");
if (connect(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
close(sock);
throw runtime_error("connecting stream socket");
}
if (write(sock, msg.c_str(), msg.length()) < 0){
throw runtime_error("writing on stream socket");
close(sock);
}
bzero(buf, sizeof(buf));
int rval = read(sock, buf, 1024);
return string( reinterpret_cast< char const* >(buf), rval );
}
这是我的服务器函数(稍微复杂一点,类型vSocketHandler代表我调用来处理请求的函数):
void UnixSocketServer::listenRequests(vSocketHandler requestHandler){
int sock, msgsock, rval;
struct sockaddr_un server;
char buf[SOCKET_BUFFER_SIZE];
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
throw runtime_error("opening stream socket");
}
server.sun_family = AF_UNIX;
strcpy(server.sun_path, SOCKET_FILE_PATH);
if (bind(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un))) {
throw runtime_error("binding stream socket");
}
listen(sock, SOCKET_MAX_CONNECTIONS);
while(true) {
msgsock = accept(sock, 0, 0);
if (msgsock == -1){
throw runtime_error("accept socket");
} else {
bzero(buf, sizeof(buf));
if((rval = read(msgsock, buf, SOCKET_BUFFER_SIZE)) < 0)
throw runtime_error("reading stream message");
else if (rval == 0){
//do nothing, client closed socket
break;
} else {
string msg = requestHandler(string( reinterpret_cast< char const* >(buf), rval ));
if(write(msgsock, msg.c_str(), msg.length()) < 0)
throw runtime_error("sending stream message");
}
close(msgsock);
}
}
close(sock);
unlink(SOCKET_FILE_PATH);
}
【问题讨论】: