【发布时间】:2015-06-22 22:42:36
【问题描述】:
我是这个论坛的新手,如果我的问题没有被正确提出,我很抱歉。我会尽量说清楚。
我正在尝试在 Linux 中编写两个程序(client.c 和 server.c,使用 TCP 套接字),其行为如下:
客户端向服务器发送消息,其中包含要由服务器运行的命令(ls、mkdir 等)。
服务器运行这些命令,并将程序输出(stdout)发送回客户端。
客户端打印收到的程序输出。
到目前为止,我有这个:
server.c:
/*After creating socket with socket(), binding to address and port,
putting in listening mode and accepting connection*/
dup2(sock_client,1); //redirect stdout
while(1){
recv(sock_client,buf,MAX_MSG_LENGTH,0);
/*If the message recieved was END_STRING, exit this loop*/
if (strncmp(buf, END_STRING, MAX_MSG_LENGTH) == 0)
break;
system(buf);
}
client.c:
/*After creating socket and connecting*/
while(fgets(buf,MAX_MSG_LENGTH,stdin)){
send(sock,buf,MAX_MSG_LENGTH,0);
if (!strncmp(buf,END_STRING,MAX_MSG_LENGTH)){
/*If the message recieved was END_STRING, exit this loop*/
break;
}
read(sock,buf,MAX_MSG_LENGTH); //read stdout from program
printf("%s\n",buf);
}
我的问题是,如果一个命令的输出很长,在显示下一个命令的输出时会留下一些“垃圾”,所以我想知道是否有办法刷新套接字(显然不是,基于我的谷歌研究),或者可能以其他方式完成预期的服务器-客户端行为。
谢谢!
编辑:
好的,我已经完成了客户端。代码如下:
client.c:
/* After creating socket and connecting*/
while(fgets(buf,MAX_MSG_LENGTH,stdin)){
send(sock,buf,MAX_MSG_LENGTH,0);
if (!strncmp(buf,END_STRING,MAX_MSG_LENGTH)){
/*If the message recieved was END_STRING, exit this loop*/
break;
}
while(1){
read_size = read(sock,buf,MAX_MSG_LENGTH);
/*Print read_size characters from buf*/
printf("%.*s\n", read_size, buf);
if (read_size < MAX_MSG_LENGTH){
/*Keep on reading until read_size < MAX_MSG_LENGTH, then exit this loop*/
break;
}
}
/*Clear buffer, just in case*/
for (i = 0; i < MAX_MSG_LENGTH; i++){
buf[i] = 0;
}
就像注释一样,如果发送到服务器的命令没有任何标准输出(例如,mkdir new_directory),此程序将无法正常工作,因为在这种情况下,read() 将离开客户端永久阻塞,导致服务器永远不会收到下一个要运行的命令或END_STRING 消息从客户端离开程序。您可能可以通过使用非阻塞套接字并使用select() 从套接字读取来解决此问题,就像 synther 建议的那样。此外,在服务器中,在system(buf); 行之后,您应该添加fflush(0),这将刷新所有缓冲区(包括套接字,如果客户端发送的命令输出非常短,这可能很有用)。
非常感谢!
【问题讨论】:
-
首先,服务器将输出发回哪里?可能是客户端没有消耗服务器发送的所有数据。调用 read 直到它返回一个小于 MAX_MSG_LENGTH 的值。
-
@SelçukCihan 更好的是,调用
read()直到它表明没有更多的数据要读取,或者在协议中构建这样的指标,因为,特别是对于网络套接字,读取的数据少于之前的数据请求是相当正常的,并不表示数据结束...
标签: c linux sockets stdout dup2