* exits back to the shell:
*/
static void bail(const char *on_what)
{
if(errno!=0)
{
fputs(strerror(errno),stderr);
fputs(": ",stderr);
}
fputs(on_what,stderr);
fputc('/n',stderr);
exit(1);
}
int main(int argc,char **argv)
{
int z;
int s = -1; /* Socket */
int so_type = -1; /* Socket type */
socklen_t optlen; /* Option length */
/*
* Create a TCT/IP socket to use:
*/
s = socket(PF_INET,SOCK_STREAM,0);
if(s==-1)
bail("socket(2)");
/*
* Get socket option SO_TYPE:
*/
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,而客户端仍可以继续被服务。然而,却不会有新的连接连接到服务器,因为并没有服务器新的连接(服务器PID 926已被杀死)
现 在如果我们重启服务器来新的连接,就会出现问题。当新的服务器进程试着绑定IP地址192.168.0.1:9099时,bind函数就会返回 EADDRINUSE的错误代码。这个错误代码表明IP已经在9099端口上使用。这是因为进程PID 927仍然在忙于服务一个客户端。socket setsockopt地址192.168.0.1:9099仍为这个进程所使用。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/tongxinshuyu/article-46983-6.html
那就是统一之时