当前位置: 技术问答>linux和unix
请教:SOCKET编程的问题.
来源: 互联网 发布时间:2015-08-05
本文导语: 各位高手: 兄弟最近刚开始学习在Linux下GCC编程。我想做一个程序,实现如下功能。 在服务器上侦听工作站发送来的心跳包。如果心跳包接收不到,服务器在 2分钟后关闭。使用TCP连接,使用Select监视套接字是否收到...
各位高手:
兄弟最近刚开始学习在Linux下GCC编程。我想做一个程序,实现如下功能。
在服务器上侦听工作站发送来的心跳包。如果心跳包接收不到,服务器在
2分钟后关闭。使用TCP连接,使用Select监视套接字是否收到数据。
可是,好象不管套接字是否收到数据Select都会在设定的超时时间返回超
时信息。很困惑啊。想实现前述功能应该如何修改我的代码?
我的代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MYPORT 3490 /*用户所连接的端口号*/
#define BACKLOG 1 /*最大连接数*/
main()
{
int sockfd,new_fd; /*在sockfd上监听,在new_fd上建立新的连接*/
struct sockaddr_in my_addr; /*本机地址信息*/
struct sockaddr_in their_addr; /*客户端计算机地址信息*/
int sin_size;
int numbytes; /*接收到的字节数*/
char buf[4]; /*一次最多接收4个字节*/
fd_set readfds;
fd_set readfds_new;
struct timeval tv; /*超时时间*/
struct timeval tv_new;
tv.tv_sec=20;
tv.tv_usec=0;
tv_new.tv_sec=120;
tv_new.tv_usec=0;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
my_addr.sin_family=AF_INET; /*host byte order*/
my_addr.sin_port=htons(MYPORT); /*short,network byte order*/
my_addr.sin_addr.s_addr=INADDR_ANY; /*auto-fill with my IP*/
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG) == -1)
{
perror("listen");
exit(1);
}
FD_ZERO(&readfds); /*清空输入文件描述符集*/
FD_SET(sockfd,&readfds);
select(sockfd+1,&readfds,NULL,NULL,&tv);
if(FD_ISSET(sockfd,&readfds))
{
printf("to be accept connect.n");
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&sin_size)) == -1)
{
perror("accept");
}
printf("server: got connection from %sn",inet_ntoa(their_addr.sin_addr));
while(1)
{
FD_ZERO(&readfds_new); /*清空输入文件描述符集*/
FD_SET(new_fd,&readfds_new);
select(new_fd+1,&readfds_new,NULL,NULL,&tv_new);
if(FD_ISSET(new_fd,&readfds_new))
{
if((numbytes=recv(new_fd,buf,3,0)) == -1)
{
perror("recv");
continue;
}
printf("Connected.%dn",numbytes);
}
else /*如果120秒内没有收到工作站发来的心跳包,关机*/
{
printf("shoutdown this computer now.n");
system("shutdown -h now");/*关机*/
exit(0);
}
}
}
else /*如果20秒内工作站没有连接,提示检查网络连接*/
{
printf("Check your newwork.n");
exit(-1);
}
}
兄弟最近刚开始学习在Linux下GCC编程。我想做一个程序,实现如下功能。
在服务器上侦听工作站发送来的心跳包。如果心跳包接收不到,服务器在
2分钟后关闭。使用TCP连接,使用Select监视套接字是否收到数据。
可是,好象不管套接字是否收到数据Select都会在设定的超时时间返回超
时信息。很困惑啊。想实现前述功能应该如何修改我的代码?
我的代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MYPORT 3490 /*用户所连接的端口号*/
#define BACKLOG 1 /*最大连接数*/
main()
{
int sockfd,new_fd; /*在sockfd上监听,在new_fd上建立新的连接*/
struct sockaddr_in my_addr; /*本机地址信息*/
struct sockaddr_in their_addr; /*客户端计算机地址信息*/
int sin_size;
int numbytes; /*接收到的字节数*/
char buf[4]; /*一次最多接收4个字节*/
fd_set readfds;
fd_set readfds_new;
struct timeval tv; /*超时时间*/
struct timeval tv_new;
tv.tv_sec=20;
tv.tv_usec=0;
tv_new.tv_sec=120;
tv_new.tv_usec=0;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
my_addr.sin_family=AF_INET; /*host byte order*/
my_addr.sin_port=htons(MYPORT); /*short,network byte order*/
my_addr.sin_addr.s_addr=INADDR_ANY; /*auto-fill with my IP*/
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
if(listen(sockfd,BACKLOG) == -1)
{
perror("listen");
exit(1);
}
FD_ZERO(&readfds); /*清空输入文件描述符集*/
FD_SET(sockfd,&readfds);
select(sockfd+1,&readfds,NULL,NULL,&tv);
if(FD_ISSET(sockfd,&readfds))
{
printf("to be accept connect.n");
sin_size = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&sin_size)) == -1)
{
perror("accept");
}
printf("server: got connection from %sn",inet_ntoa(their_addr.sin_addr));
while(1)
{
FD_ZERO(&readfds_new); /*清空输入文件描述符集*/
FD_SET(new_fd,&readfds_new);
select(new_fd+1,&readfds_new,NULL,NULL,&tv_new);
if(FD_ISSET(new_fd,&readfds_new))
{
if((numbytes=recv(new_fd,buf,3,0)) == -1)
{
perror("recv");
continue;
}
printf("Connected.%dn",numbytes);
}
else /*如果120秒内没有收到工作站发来的心跳包,关机*/
{
printf("shoutdown this computer now.n");
system("shutdown -h now");/*关机*/
exit(0);
}
}
}
else /*如果20秒内工作站没有连接,提示检查网络连接*/
{
printf("Check your newwork.n");
exit(-1);
}
}
|
每次在执行下面这句代码之前,需要重设一下tv_new的值,这点至关重要
select(new_fd+1,&readfds_new,NULL,NULL,&tv_new);
select(new_fd+1,&readfds_new,NULL,NULL,&tv_new);