我想将命令的输出(使用exec执行)重定向到套接字,以便我可以从客户端读取并将其写入客户端的标准输出。我在exec之前使用了dup2()并从套接字读取,但是我不知道何时告诉客户端停止读取,因此它正在等待其他字节。
这是代码(您可以在client.c中找到问题所在的注释)。
编辑:我自己找到了解决方案,客户端仍在等待读取其他字节,因为在父服务器进程中套接字描述符仍处于打开状态,只需要关闭它即可。
server.c
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <stdio.h>
int main(int argc, char *argv[]){
int sd,sd2,n1,n2;
char message[100];
pid_t pid;
struct sockaddr_in my_addr;
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(5200);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
sd=socket(PF_INET,SOCK_STREAM,0);
if(sd<0){
write(STDOUT_FILENO,"Socket error\n",strlen("Socket error\n"));
exit(1);
}
if(bind(sd,(struct sockaddr *)&my_addr,sizeof(my_addr))<0){
write(STDOUT_FILENO,"Bind error\n",strlen("Bind error\n"));
exit(1);
}
if(listen(sd,5)<0){
write(STDOUT_FILENO,"Listen error\n",strlen("Listen error\n"));
exit(1);
}
while(1){
sd2=accept(sd,NULL,NULL);
if(sd2<0){
write(STDOUT_FILENO,"Accept error\n",strlen("Accept error\n"));
exit(1);
}
if((pid=fork())==0){
while(read(sd2,&n1,sizeof(int))!=0){
n2=ntohl(n1);
read(sd2,message,n2);
message[n2]='\0';
if(strcmp(message,"EXIT")==0){
break;
}else if(strcmp(message,"SH")==0){
}else if(strcmp(message,"FS")==0){
dup2(sd2,STDOUT_FILENO);
execl("/bin/df","df",(char *)NULL);
}else{
//do nothing
}
}
write(STDOUT_FILENO,"Server-child terminated\n",strlen("Server-child terminated\n"));
close(sd2);
exit(0);
}
close(sd2); // ADD THIS
}
}
client.c
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]){
int sd,n1,n2;
char message[100];
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(5200);
inet_aton("127.0.0.1",&server_addr.sin_addr);
sd=socket(PF_INET,SOCK_STREAM,0);
if(sd<0){
write(STDOUT_FILENO,"Client Socket error\n",strlen("Client Socket error\n"));
exit(1);
}
if(connect(sd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){
write(STDOUT_FILENO,"Connect error\n",strlen("Connect error\n"));
exit(1);
}
while(1){
n1=read(STDIN_FILENO,&message,100);
n1=n1-1;
message[n1]='\0';
n2=htonl(n1);
write(sd,&n2,sizeof(int));
write(sd,message,n1);
if(strcmp(message,"EXIT")==0){
break;
}else if(strcmp(message,"SH")==0){
}else if(strcmp(message,"FS")==0){
while((n1=read(sd,message,99))!=0){ // Here is the problem
message[n1]='\0';
write(STDOUT_FILENO,message,strlen(message));
}
}else{
//do nothing
}
}
write(STDOUT_FILENO,"Client terminated\n",strlen("Client terminated\n"));
close(sd);
exit(0);
}