linux下setsockopt()与getsockopt()函数的使用(关于KEEPALIVE属性)
发表于 : 2008-08-29 16:15
首先知道setsockopt()函数的KEEPALIVE属性是周期地测试连接是否仍存活,
我上网查了很多资料还是不知道如何使用,
最后硬着头皮自己写了一个服务器端和一个客户端的套接字连接
分别设置了两端的KEEPALIVE属性为打开
服务器端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<error.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/wait.h>
#include<arpa/inet.h>
#include<unistd.h>
#define SERVPORT 6000 //设定服务器服务端口为6000
#define MAX_LISTEN_SOCK_NUM 20 //设定可监听套接字的最大个数为20
int main()
{
//sockfd为本地监听套接字标识符,client_fd为客户端套接字标识符
int sockfd,client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in client_addr;
//创建本地监听套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("套接字创建失败!\n");
exit(1);
}
//设置套接字的属性使它能够在计算机重启的时候可以再次使用套接字的端口和IP
int err,sock_reuse=1;
err=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char *)&sock_reuse,sizeof(sock_reuse));
if(err!=0){
printf("套接字可重用设置失败!\n");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//绑定套接字
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("绑定失败!\n");
exit(1);
}
//设置监听
if((listen(sockfd,MAX_LISTEN_SOCK_NUM))==-1){
perror("设置监听失败!\n");
exit(1);
}
printf("套接字进入监听状态,等待请求连接:\n");
//int time_to_quit=1;
//while(time_to_quit){ //可以通过设置time_to_quit来主动关闭服务器端
while(1){
//有连接请求时进行连接
socklen_t sin_size=sizeof(struct sockaddr_in);
if((client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&sin_size))==-1){
perror("接受连接失败!\n");
continue;
}
int opt;
socklen_t len=sizeof(int);
if((getsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&opt,&len))==0){
printf("SO_KEEPALIVE Value: %d\n", opt);
}
printf("接到一个来自%s的连接\n",inet_ntoa(client_addr.sin_addr));
//创建子进程来处理已连接的客户端套接字
if(send(client_fd,"您好,您已经连接成功!\n",50,0)==-1){
perror("发送通知信息失败!\n");
exit(0);
}
}
close(client_fd);
return 0;
}
客户端:
#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#define MAXDATASIZE 100 /*每次最大数据传输量*/
int main()
{
int sockfd,nbytes,serv_port;
char buf_serv_ip[16],buf[26];
struct sockaddr_in serv_addr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("创建套接字失败!\n");
exit(1);
}
//创建套接字成功后设置其可重用的属性
int KeepAlive=1;
socklen_t KPlen=sizeof(int);
if(setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(char *)&KeepAlive,KPlen)!=0){
perror("设置周期测试连接是否仍存活失败!\n");
exit(1);
}
printf("请输入要连接主机的IP地址:\n");
scanf("%s",buf_serv_ip);
printf("请输入要连接主机的端口号:\n");
scanf("%d",&serv_port);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(buf_serv_ip);
serv_addr.sin_port=htons(serv_port);
bzero(&(serv_addr.sin_zero),8);
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
perror("连接服务器失败!\n");
exit(1);
}
printf("连接服务器成功!\n");
//在此处可以先接受判断将要接受数据的长度再创建数组
if((nbytes=recv(sockfd,buf,26,0))==-1){
perror("接受数据失败!\n");
exit(1);
}
buf[nbytes]='\0';
printf("接受的数据为:%s\n",buf);
close(sockfd);
return 0;
}
分别在两个终端运(在同一个主机上)行:先启动服务器端;再启动客户端,向服务器端请求连接,连接成功后,客户端套接字关闭,服务器端套接字始终打开,等待两个小时多也没有反应,
肯请高手指点:
(1)这样做能达到预期报告连接是否仍存在的效果吗,
(2)不能的话应该如何做,
(3)还有getsockopt()的相关功能又是什么哪?在上面的程序中没有用到该函数
(4)看了unix网络编程上的一点关于该问题的解释还是不明白,因为她提到要两个小时才回应,但等了撒小时也没有反应,她还说可以缩短时间,我却不知道如何缩短
我上网查了很多资料还是不知道如何使用,
最后硬着头皮自己写了一个服务器端和一个客户端的套接字连接
分别设置了两端的KEEPALIVE属性为打开
服务器端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<error.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/wait.h>
#include<arpa/inet.h>
#include<unistd.h>
#define SERVPORT 6000 //设定服务器服务端口为6000
#define MAX_LISTEN_SOCK_NUM 20 //设定可监听套接字的最大个数为20
int main()
{
//sockfd为本地监听套接字标识符,client_fd为客户端套接字标识符
int sockfd,client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in client_addr;
//创建本地监听套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("套接字创建失败!\n");
exit(1);
}
//设置套接字的属性使它能够在计算机重启的时候可以再次使用套接字的端口和IP
int err,sock_reuse=1;
err=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(char *)&sock_reuse,sizeof(sock_reuse));
if(err!=0){
printf("套接字可重用设置失败!\n");
exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
//绑定套接字
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("绑定失败!\n");
exit(1);
}
//设置监听
if((listen(sockfd,MAX_LISTEN_SOCK_NUM))==-1){
perror("设置监听失败!\n");
exit(1);
}
printf("套接字进入监听状态,等待请求连接:\n");
//int time_to_quit=1;
//while(time_to_quit){ //可以通过设置time_to_quit来主动关闭服务器端
while(1){
//有连接请求时进行连接
socklen_t sin_size=sizeof(struct sockaddr_in);
if((client_fd=accept(sockfd,(struct sockaddr *)&client_addr,&sin_size))==-1){
perror("接受连接失败!\n");
continue;
}
int opt;
socklen_t len=sizeof(int);
if((getsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(char*)&opt,&len))==0){
printf("SO_KEEPALIVE Value: %d\n", opt);
}
printf("接到一个来自%s的连接\n",inet_ntoa(client_addr.sin_addr));
//创建子进程来处理已连接的客户端套接字
if(send(client_fd,"您好,您已经连接成功!\n",50,0)==-1){
perror("发送通知信息失败!\n");
exit(0);
}
}
close(client_fd);
return 0;
}
客户端:
#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#define MAXDATASIZE 100 /*每次最大数据传输量*/
int main()
{
int sockfd,nbytes,serv_port;
char buf_serv_ip[16],buf[26];
struct sockaddr_in serv_addr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("创建套接字失败!\n");
exit(1);
}
//创建套接字成功后设置其可重用的属性
int KeepAlive=1;
socklen_t KPlen=sizeof(int);
if(setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,(char *)&KeepAlive,KPlen)!=0){
perror("设置周期测试连接是否仍存活失败!\n");
exit(1);
}
printf("请输入要连接主机的IP地址:\n");
scanf("%s",buf_serv_ip);
printf("请输入要连接主机的端口号:\n");
scanf("%d",&serv_port);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(buf_serv_ip);
serv_addr.sin_port=htons(serv_port);
bzero(&(serv_addr.sin_zero),8);
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
perror("连接服务器失败!\n");
exit(1);
}
printf("连接服务器成功!\n");
//在此处可以先接受判断将要接受数据的长度再创建数组
if((nbytes=recv(sockfd,buf,26,0))==-1){
perror("接受数据失败!\n");
exit(1);
}
buf[nbytes]='\0';
printf("接受的数据为:%s\n",buf);
close(sockfd);
return 0;
}
分别在两个终端运(在同一个主机上)行:先启动服务器端;再启动客户端,向服务器端请求连接,连接成功后,客户端套接字关闭,服务器端套接字始终打开,等待两个小时多也没有反应,
肯请高手指点:
(1)这样做能达到预期报告连接是否仍存在的效果吗,
(2)不能的话应该如何做,
(3)还有getsockopt()的相关功能又是什么哪?在上面的程序中没有用到该函数
(4)看了unix网络编程上的一点关于该问题的解释还是不明白,因为她提到要两个小时才回应,但等了撒小时也没有反应,她还说可以缩短时间,我却不知道如何缩短