client.c文件中在建立socket后有一句
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
SO_REUSEADDR允许重用本地地址。
client.c文件在bind之后的connec_t函数中,
先将socket设为非阻塞,然后connect 然后select然后再将socket状态改为原来的。
这样做的目的是select超时就退出了。
如果不这样,client端一直在connect状态,没有超时退出这个操作。
int connect_t(int s, struct sockaddr *svr, time_t timeout)
{ #if defined(VTUN_SOCKS) && VTUN_SOCKS == 2 /* Some SOCKS implementations don't support * non blocking connect */ return connect(s,svr,sizeof(struct sockaddr));#else int sock_flags; fd_set fdset; struct timeval tv;tv.tv_usec=0; tv.tv_sec=timeout;
sock_flags=fcntl(s,F_GETFL); if( fcntl(s,F_SETFL,O_NONBLOCK) < 0 )//设置s为非阻塞 return -1;
if( connect(s,svr,sizeof(struct sockaddr)) < 0 && errno != EINPROGRESS)
return -1;FD_ZERO(&fdset);
FD_SET(s,&fdset); if( select(s+1,NULL,&fdset,NULL,timeout?&tv:NULL) > 0 ){ int l=sizeof(errno); errno=0; getsockopt(s,SOL_SOCKET,SO_ERROR,&errno,&l); } else errno=ETIMEDOUT;fcntl(s,F_SETFL,sock_flags);
if( errno )
return -1;return 0;
#endif}//end connect_t
除此之外client端还有SO_KEEPALIVE和地址重用设置。
server端有个getpeername等选项无关紧要。