实验要求:实现一个远程编译系统
执行过程:客户端提交c语言代码文件,在服务端编译连接,服务端执行文件后把结果返回给客户端。
细节说明:
(1)在执行外部命令时,要在该函数下创建子进程。
if
((cpid
=
fork())
!=
0
)
... {
return 0;
}
else
... {
execl(argv[0], argv[1], argv[2], (char *)0);
exit(0);
}
... {
return 0;
}
else
... {
execl(argv[0], argv[1], argv[2], (char *)0);
exit(0);
}
(2)服务端在接收客户端传送的二进制流时,为了同步,需要等待;否则,经过实验,会造成服务端数据丢失。
while
(
!
flag)
... {
if(recv(tsockfd, package, 1024, 0)<0)
...{
perror("recv");
exit(1);
}
else
...{
flag=1;
}
}
... {
if(recv(tsockfd, package, 1024, 0)<0)
...{
perror("recv");
exit(1);
}
else
...{
flag=1;
}
}
(3)由于socket传输的是二进制流,所以在接收字符串时要在数据结尾增加“字符串结束符”。
numb
=
recv(tsockfd, str,
10
,
0
);
if (numb < 0 )
... {
perror("recv");
exit(1);
}
str[numb] = '/0';
if (numb < 0 )
... {
perror("recv");
exit(1);
}
str[numb] = '/0';
(4)服务端接收客户端的数据时,除了创建子进程外,还需要通过管道进行进程内通信,用来传送子进程运行的结果。
if
(pipe(fd)
==-
1
)
... {
printf("create pipe error! ");
exit(1);
}
switch (child_pid = fork())
... {
case 0:
...{
close(fd[0]);
if(put()==0)
...{
sprintf(reply, "upload successfully!");
write(fd[1], reply, strlen(reply));
}
else
...{
sprintf(reply, "upload error!");
write(fd[1], reply, strlen(reply));
}
exit(0);
break;
}
case -1:
...{
perror("fork error");
break;
}
default:
...{
int len;
close(fd[1]);
len=read(fd[0], reply, sizeof(reply));
reply[len]='/0';
... {
printf("create pipe error! ");
exit(1);
}
switch (child_pid = fork())
... {
case 0:
...{
close(fd[0]);
if(put()==0)
...{
sprintf(reply, "upload successfully!");
write(fd[1], reply, strlen(reply));
}
else
...{
sprintf(reply, "upload error!");
write(fd[1], reply, strlen(reply));
}
exit(0);
break;
}
case -1:
...{
perror("fork error");
break;
}
default:
...{
int len;
close(fd[1]);
len=read(fd[0], reply, sizeof(reply));
reply[len]='/0';
}
}