您的位置:首页 > 理论基础 > 计算机网络

网络编程(29)—— socket的close函数以及shutdown函数在多进程服务器中的不同表现(二)

2016-12-07 00:21 387 查看
        本文紧接着上一遍文章《socket的close函数以及shutdown函数在多进程服务器中的不同表现(一)》,来验证上文中提到的几个结论:

1、 复制后的socket描述符真的指向同一个socket吗?

    为了验证这个问题,我们先创建一个socket,然后复制一份改socket描述符的副本,再分别打印这两个socket描述符,若描述符打印结果一致,说明指向同一个socket。

int main()
{
int sock1,sock2;
sock1=socket(AF_INET,SOCK_STREAM,0);
sock2=sock1;
printf("sock1=%d\n",sock1);
printf("sock2=%d\n",sock2);
return 0;
}
        验证原理很简单,代码不再赘述,结果如下:

[Hyman@Hyman-PC multiProcess]$ ./a.out
sock1=3
sock2=3
        很显然,结果证明了我们的结论,复制后的socket描述符指向同一个socket。

 

2、 关闭多进程中指向同一个socket的描述符中的一个,真的无法关闭这个socket吗

        为了验证这个问题,我们进行下面的试验。

        在试验之前,我们要先准备一个回声服务器,之前我很多文章中都有过描述,这里不再赘述,我们在客户端中验证这个问题,请看下面的代码:

int main(int argc,char* argv[])
{
pid_t pid;
int sout,result;
int sock;
struct sockaddr_in addr;
char buf[1024];
sock=socket(AF_INET,SOCK_STREAM,0);
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(argv[1]);
addr.sin_port=htons(atoi(argv[2]));
connect(sock,(struct sockaddr*)&addr,sizeof(addr));
pid=fork();
if(pid==0)
{
close(sock);
}
else
{
sleep(2);
write(sock,"hello world\n",12);
read(sock,buf,1024);
fputs(buf,stdout);
}
return 0;
}
      代码中用fork()创建了一个子进程,然后在子进程中关闭了socket,而主进程中,为了防止在子进程close(sock)之前执行write(sock,"hello
world\n",12);这段代码,sleep了2秒钟,接着发送”hello world”,如果结论正确,此时的”hello world”字符串是可以被回声服务器发送回来的,然后打印接收到的字符串。也就是说结论成立的话,程序会打印一行”hello
world”。

           是不是和我们预期的结果一致呢?请看下面的结果:

[Hyman@Hyman-PC multiProcess]$ ./a.out 127.0.0.1 9990
hello world
     不出所料,close()函数果然未生效,证明了我们的结论。
     值得注意的是我们要验证的结论:在多进程中存在同一个socket的副本的话,才会无法close()掉!因为不管标准输出还是socket都是系统级别的存在,操作系统会负责统计每个进程中是否存在指向同一个socket的文件描述符,从而根据文件描述符的数量,控制对应socket的关闭。

3、 Shutdown函数这么神奇?可以同时关闭多个socket描述符?

     验证这个问题,其实非常简单,只需要将上述客户端代码中子进程关闭socket的函数close换成shutdown即可:

shutdown(sock,SHUT_WR);        我们会发现,程序不再打印数据:
[Hyman@Hyman-PC multiProcess]$ ./a.out 127.0.0.1 9990
[Hyman@Hyman-PC multiProcess]$
OK,所有结论验证成功!

 

 Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone
git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL29
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: