*/
optlen = sizeof so_type;
z = getsockopt(s,SOL_SOCKET,SO_TYPE,&so_type,&optlen);
if(z)
bail("getsockopt(s,SOL_SOCKET,"
"SO_TYPE)");
assert(optlen == sizeof so_type);
/*
* Report the result:
*/
printf("Socket s: %d\n",s);
printf(" SO_TYPE : %d\n",so_type);
printf(" SO_STREAM = %d\n",SOCK_STREAM);
close(s);
return 0;
}
程序的运行结果如下:
$./gettype
Socket s: 3
SO_TYPE : 1
SO_STREAM = 1
设置SO_REUSEADDR选项
在第11章,"并发客户端服务器"的第一部分中,提供并测试了一个使用fork系统调用设计的服务器。图12.1显示了在一个telnet命令与服务器建立连接之后的三个步骤。
这些步骤如下:
1 启动服务器进程(PID 926)。他客户端连接。
2 启动客户端进程(telnet命令),并且连接到服务器进程(PID 926)。
3 通过fork调用创建服务器子进程,这会保留的原始的父进程(PID 926)并且创建一个新的子进程(PID 927)。
4 连接的客户端套接口由服务器父进程(PID 926)关闭,仅在子进程(PID 927)中保持连接的客户端套接口处理打开状态。
5 telnet命令与服务器子进程(PID 927)随意交互,而独立于父进程(PID 926)。
在步骤5,有两个套接动:
服务器(PID 926)192.168.0.1:9099
客户端由套接口192.168.0.1:9099进行服务(PID 927),他连接到客户端地址192.168.0.2:1035
客户端由进程ID 927进行服务。这意味着我们可以杀掉进程ID 926,而客户端仍可以继续被服务。setsockopt然而,却不会有新的连接连接到服务器,因为并没有服务器新的连接(服务器PID 926已被杀死)
现在如果我们重启服务器来新的连接,就会出现问题。当新的服务器进程试着绑定IP地址192.168.0.1:9099时,bind函数就会返回 EADDRINUSE的错误代码。这个错误代码表明IP已经在9099端口上使用。这是因为进程PID 927仍然在忙于服务一个客户端。地址192.168.0.1:9099仍为这个进程所使用。
这个问题的解决办法就是杀掉进程927,这个关闭套接口并且释放IP地址和端口。然而,如果正在被服务的客户是我们所在公司的CEO,这样的做法似乎不是一个选择。同时,其他的部门也会抱怨我们为什么要重新启动服务器。
这个问题的一个好的解决办法就是使用SO_REUSEADDR套接口选项。所有的服务器都应使用这个选项,除非有一个更好的理由不使用。为了有效的使用这个选项,我们应在连接的服务器中执行下面的操作:
1 使用通常的socket函数创建一个套接口
2 调用setsockopt函数设置SO_REUSEADDR为TRUE
3 调用bind函数
套接口现在被标记为可重用。如果服务器进程因为任何原因终止,我们可以重新启动这个服务器。当一个客户正为另一个服务器进程使用同一个IP和端口号进行服务时尤其如此。
为了有效的使用SO_REUSEADDR选项,需要考虑下面的情况:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-49663-6.html
为何不说现在人多
天了噜
短头发的不错