免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 17153 | 回复: 23
打印 上一主题 下一主题

在程序中如何检测出网络断开(直接拔掉网线来测试)? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-09-26 12:45 |只看该作者 |倒序浏览
测试表明:把网线拔掉后,写操作在buffer满(13032Byte)时,会祖塞(在祖塞情况下).不会产生任何信号(与一些资料不符),若设置写超时,则会返回EGAIN错误.但这个错误也应该会在网络祖塞情况下产生,不能用来作为断开的条件.
请教各位老兄是如何做的?多谢!@!!

论坛徽章:
0
2 [报告]
发表于 2005-09-26 12:53 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

系统阻塞够了应该会给write一个错误的返回值吧

论坛徽章:
0
3 [报告]
发表于 2005-09-26 13:03 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

您所指的就是ifconfig所显示的网卡的状态,也就是Active为网线插上,否则为断开?
您可以查看您系统中ifconfig实现里的相关代码,不长

论坛徽章:
0
4 [报告]
发表于 2005-09-26 13:22 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

这个程序可以查看网线是否连接
可是我觉得这个东西并不能解决你的问题

  1. #include <sys/types.h>;
  2. #include <sys/socket.h>;
  3. #include <sys/ioctl.h>;
  4. #include <net/if.h>;
  5. #include <linux/sockios.h>;
  6. #include <linux/types.h>;

  7. struct mii_data {
  8.     __u16   phy_id;
  9.     __u16   reg_num;
  10.     __u16   val_in;
  11.     __u16   val_out;
  12. };

  13. int main()
  14. {
  15.     int skfd;
  16.     struct ifreq ifr;
  17.     struct mii_data *mii;

  18.     if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  19.         perror("socket");
  20.         exit(1);
  21.     }

  22.     strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
  23.     ifr.ifr_name[IFNAMSIZ-1] = 0;

  24.     if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) {
  25.         perror("ioctl");
  26.         exit(1);
  27.     }

  28.     mii = (struct mii_data *)&ifr.ifr_data;
  29.     mii->;reg_num = 0x01;

  30.     if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
  31.         perror("ioctl");
  32.         exit(1);
  33.     }
  34.     if (mii->;val_out & 0x0004)
  35.         puts("link ok");
  36.     else
  37.         puts("no link");

  38.     close(skfd);

  39.     return 0;
  40. }
复制代码

论坛徽章:
0
5 [报告]
发表于 2005-09-26 13:32 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

原帖由 "tyq7821" 发表:
测试表明:把网线拔掉后,写操作在buffer满(13032Byte)时,会祖塞(在祖塞情况下).不会产生任何信号(与一些资料不符),若设置写超时,则会返回EGAIN错误.但这个错误也应该会在网络祖塞情况下产生,不能用来作为断开的条件.
..........


可以用select超时。

论坛徽章:
0
6 [报告]
发表于 2005-09-26 13:49 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

select估计不行
我觉得还是老老实实等待write出错为好

论坛徽章:
0
7 [报告]
发表于 2005-09-26 14:01 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

1\只有在getsockopt,SO_SNDTIMEO情况下write 会回返回-1,errno为EGAIN,但这个错误码也应该会在网络祖塞情况下产生,不能用来作为断开的条件.
2\用select超时则select会超时,超时不能作为断开的条件.
3\bleem1998     
天使的程序我看一下,多谢.
补充,测试程序及条件如下:

1\
#include <sys/types.h>;
#include <sys/socket.h>;
#include <netinet/in.h>;
#include <unistd.h>;

int main(int argc,char **argv)
{
  int mysocket;
  int acceptport;
  struct sockaddr_in inaddr,outaddr;
  int port;
  mysocket = socket(PF_INET, SOCK_STREAM, 0);
  inaddr.sin_family = AF_INET;
  inaddr.sin_port = htons(5060);
  inaddr.sin_addr.s_addr = htonl(INADDR_ANY);

  bind(mysocket,(struct sockaddr *)&inaddr,sizeof(inaddr));
  listen(mysocket, 10);
  int len = sizeof(outaddr);
  acceptport = accept(mysocket, (struct sockaddr *)&outaddr, &len);
  struct timeval oldval,newval;
  int status;  
/*   int lentime=sizeof(oldval); */
/*   status = getsockopt(acceptport, SOL_SOCKET, SO_SNDTIMEO, &oldval, &lentime); */
/*   printf("the sndtimeo is:%d,%d\n",oldval.tv_sec,oldval.tv_usec); */
/*   newval.tv_sec=3; */
/*   newval.tv_usec=0; */

/*   status = setsockopt(acceptport, SOL_SOCKET, SO_SNDTIMEO, &newval, lentime); */

  char content[1000]="Test!!!\r\n";
  char buff[50];
  while (1)
    {
      status = write(acceptport, content, sizeof(content));
      perror("The errno is:";
      //      status =read (acceptport, buff, 50);
      // printf("read %d, and %s",status, buff);
      //perror("read error.";
      sleep(2);
    }
  return 1;
}


2\
#include <netinet/in.h>;
#include <sys/socket.h>;
#include <sys/types.h>;
#include <errno.h>;
#include <unistd.h>;
int main(int argc, char **argv)
{
  int mysocket;
  struct sockaddr_in outaddr;
  int status;
  mysocket = socket (PF_INET, SOCK_STREAM, 0);
  outaddr.sin_family = AF_INET;
  outaddr.sin_port = htons(5060);
  outaddr.sin_addr.s_addr = inet_addr("19.80.116.125";
  connect(mysocket, (struct sockaddr *)&outaddr, sizeof(outaddr));
  char buff[50];
  int len;
  while(1)
    {
      len = read(mysocket, buff, 50);
      //      perror("the end is.";
      buff[len] = '\0';
      //     printf("the recv content is:%s\n",buff);
      len = write(mysocket,buff,len);
      perror("write error";
      sleep(2);
    }
  return 1;
}


测试方法:联上后修改一端的ip来模拟cdma断线重拨
现象:网络连接一直不会断开,ifconfig显示已经修改,netstat 显示连接存在.

论坛徽章:
0
8 [报告]
发表于 2005-09-26 14:12 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

或许网络只是暂时断了呢
没准一下又好了
可能TCP协议就是这个德性
如果想做到网线一断立刻退出可能要想别的怪办法才行吧

论坛徽章:
0
9 [报告]
发表于 2005-09-26 14:15 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

不是一会,我测试表明它会一直存在(netstat),除非应用程序关闭.

论坛徽章:
0
10 [报告]
发表于 2005-09-26 14:19 |只看该作者

在程序中如何检测出网络断开(直接拔掉网线来测试)?

安道理最多3分钟write就该出错返回了
你在程序里加一点代码控制一下
如果wirte出错了就打印点消息
并且close()描述符
估计这样就会消失了??
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP