它主要包含forkexecwaitpid三个步骤。
下来我来还原楼主的错误:
程序A:
#include
#include
#include
#include
#include
#include
#defineBACKLOG10
#defineMYPORT4000
intmain()
{
char*addr;
intsockfd;
intnew_fd;
structsockaddr_inmy_addr,their_addr;
intres;
intsin_size;
char*buf;
sockfd=socket(AF_INET,
SOCK_STREAM,
0);
if(sockfd==-1){
perror("socket");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(MYPORT);
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(my_addr.sin_zero),8);
res=bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr));
if(res==-1){
perror("bind");
exit(1);
}
res=listen(sockfd,
BACKLOG);
if(res==-1){
perror("listen");
exit(1);
}
system("./hello&");
sin_size=sizeof(structsockaddr_in);
new_fd=accept(sockfd,(void*)&their_addr,&sin_size);
buf=(char*)malloc(255);
if(buf==NULL){
printf("mallocfailed\n");
exit(1);
}
res=recv(new_fd,buf,255,0);
if(res==-1){
perror("recv()");
exit(1);
}
close(new_fd);
close(sockfd);
printf("recvdata:%s\n",buf);
free(buf);
return0;
}
程序B:hello,在主程序中用system("./hello&)调用。
#include
intmain(){
while(1){
sleep(1000);
}
return0;
}
编译后运行程序A。我们可以在其它终端窗口看到./A./hello正在运行,netstat-a看到,tcp4000端口被占用。
我们用Ctrl+c中断程序A模拟楼主的崩溃操作。
这时,再在其它终端窗口看看,./A没有了。./hello还在运行。netstat-a看到。4000端口还在占用。
这时再次运行./A,提示bind:Addressalreadyinuse而退出。
情况就是这样。
因为执行system时,系统会fork一个A的子进程,再去执行B.
当你的A崩溃以后,它的一个子进程实际上还在运行,它打开的端口,文件,等还在使用。
所以再次运行A时,由于自定的互斥机制而退出。
如:再次绑定端口时提示端口已在使用。
杀死B后,A的子进程结束,它的资源释放,所以才能再次运行A。
我建议楼主使用exec系列函数来启动B。