net_maintain.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: net_maintain.c
  4. 文件版本: 01.01
  5. 创建作者: xxxxxx
  6. 创建日期: 2013-03-05
  7. 功能说明: 网络维护接口
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "head.h"
  14. #ifdef LINUX_KERNEL_APP
  15. #include <linux/delay.h>
  16. #else
  17. #include <pthread.h>
  18. #include <sys/prctl.h>
  19. #endif
  20. /*------------------------------- 宏定义 --------------------------------------
  21. */
  22. /*------------------------------ 类型结构 -------------------------------------
  23. */
  24. /*------------------------------ 全局变量 -------------------------------------
  25. */
  26. #ifdef LINUX_KERNEL_APP
  27. static struct task_struct * g_ts_maintain;
  28. #else
  29. static pthread_t g_ts_maintain = 0;
  30. #endif
  31. static SOCKET g_maintain_client = RT_SOCKET_ERR;
  32. u32 g_ip_net_maintain; // 104维护工具调试客户端地址
  33. unsigned char g_net_miantain_buf[NET_RECV_MAX]; // 以太网接收缓冲区
  34. static volatile int g_net_miantain_sock_flag = NET_SOCKET_INIT;//关闭SOCKET标志
  35. #ifdef LINUX_KERNEL_APP
  36. static pid_t g_ts_maintain_pid ;
  37. #endif
  38. static int g_net_maintain_exit_flag = 0;
  39. static int port_openflag=0; //端口服务打开标志
  40. int g_mt_zombie_flag;
  41. //端口服务选择.127表示启动最后一个网络的ftp ,telnet 端口服务
  42. //128启动所有网络的ftp ,telnet 端口服务
  43. char g_port_server_sel[]={'1', '2', '8', 0};
  44. /*------------------------------ 函数声明 -------------------------------------
  45. */
  46. int _net_maintain_thread(void * unused);
  47. /*------------------------------ 外部函数 -------------------------------------
  48. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  49. */
  50. //设置socket关闭标志并等待socket关闭完成
  51. void net_maintain_set_sock_closing(int no)
  52. {
  53. struct sockaddr_in local_addr;
  54. unsigned int len = sizeof(local_addr);
  55. RUN_PARA *pRunPara=&tRunPara;
  56. unsigned int ip=0;
  57. int bflag = 0,count=0;
  58. //如果有客户端连接
  59. if(g_maintain_client != RT_SOCKET_ERR)
  60. {
  61. //获取客户端连接的IP
  62. rt_getsockname(g_maintain_client, (struct sockaddr *)&local_addr, &len);
  63. if(pRunPara->tNetPara[no].old_index==0)
  64. {
  65. //获取网卡IP
  66. rt_if_ip_get(pRunPara->tNetPara[no].old_ethid, (unsigned char *)&ip);//sunxi: 20220825 335x
  67. }
  68. else
  69. {
  70. //获取虚拟网卡上的IP地址
  71. rt_if_ip_get2(pRunPara->tNetPara[no].old_ethid, pRunPara->tNetPara[no].old_index, (unsigned char *)&ip);//sunxi: 20220825 335x
  72. }
  73. //如果是该网卡的IP并且该网卡要修改IP或MASK,则需要通知关闭socket
  74. if((htonl (ip)==local_addr.sin_addr.s_addr) && pRunPara->tNetPara[no].bInit)//sunxi: 20220825 335x
  75. {
  76. bflag = 1;
  77. }
  78. //该网卡的IP和MASK没有修改,则不需要通知关闭socket
  79. if(!bflag)
  80. {
  81. return;
  82. }
  83. g_net_miantain_sock_flag = NET_SOCKET_CLOSING; //置关闭标志
  84. //等待关闭完成
  85. while(g_net_miantain_sock_flag != NET_SOCKET_CLOSED)
  86. {
  87. if(++count>150)
  88. {
  89. rt_printf("net miantain socket close failed!\r\n");
  90. break;
  91. }
  92. msleep(20);
  93. }
  94. }
  95. }
  96. //设置socket重新创建标志
  97. void net_maintain_set_sock_initflag(void)
  98. {
  99. if(g_net_miantain_sock_flag == NET_SOCKET_CLOSED)
  100. {
  101. g_net_miantain_sock_flag = NET_SOCKET_REINIT;
  102. }
  103. }
  104. // TODO: 需要确认是否需要重新初始化
  105. #ifdef LINUX_KERNEL_APP
  106. int net_maintain_init(void)
  107. {
  108. struct sched_param sp;
  109. pid_t pid;
  110. // 如果已经初始化,退出
  111. if(g_ts_maintain)
  112. {
  113. return 0;
  114. }
  115. // 运行应用调试线程
  116. //g_ts_maintain = kthread_run(_net_maintain_thread,NULL,"net_maintain");
  117. pid = kernel_thread(_net_maintain_thread, NULL,CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
  118. g_ts_maintain = find_task_by_vpid(pid);
  119. if(IS_ERR(g_ts_maintain))
  120. {
  121. printk("ts=%p\r\n",g_ts_maintain);
  122. g_ts_maintain = NULL;
  123. return -1;
  124. }
  125. g_ts_maintain_pid = pid;
  126. // 设置调度策略和优先级
  127. sp.sched_priority = 9;
  128. sched_setscheduler(g_ts_maintain,SCHED_FIFO,&sp);
  129. // 设置进程名字
  130. set_task_comm(g_ts_maintain, "net_maintain");
  131. return 0;
  132. }
  133. #else
  134. int net_maintain_init(void)
  135. {
  136. #if 1
  137. int net=0;
  138. int ret;
  139. pthread_attr_t attr;
  140. char buf[32];
  141. // 如果已经初始化,退出
  142. if(g_ts_maintain)
  143. {
  144. return 0;
  145. }
  146. // 运行应用104线程
  147. sprintf(buf,"maintain%d",net);
  148. // 设置调度策略和优先级
  149. pthread_attr_init(&attr);
  150. pthread_attr_setschedpolicy(&attr, SCHED_FIFO); //调度
  151. struct sched_param s_parm;
  152. //s_parm.sched_priority = sched_get_priority_max(SCHED_FIFO);
  153. s_parm.sched_priority = 9;
  154. pthread_attr_setschedparam(&attr, &s_parm); //优先级
  155. //attr.__schedpolicy = SCHED_FIFO;
  156. //attr.__schedparam.sched_priority = 8;
  157. ret = pthread_create(&g_ts_maintain, &attr, (void *)_net_maintain_thread, NULL);
  158. if(!ret)
  159. {
  160. rt_printf("net = %d, ret = %d, err = %s\r\n", net, ret, strerror(ret));
  161. }
  162. return 0;
  163. #endif
  164. }
  165. #endif
  166. #ifdef LINUX_KERNEL_APP
  167. int net_maintain_exit(void)
  168. {
  169. int status;
  170. if(g_ts_maintain != NULL)
  171. {
  172. g_net_maintain_exit_flag = 1;
  173. sys_wait4(g_ts_maintain_pid, (int __user *)&status, 0, NULL);
  174. g_ts_maintain =NULL;
  175. }
  176. return 0;
  177. }
  178. #else
  179. int net_maintain_exit(void)
  180. {
  181. //int status;
  182. if(g_ts_maintain)
  183. {
  184. g_net_maintain_exit_flag = 1;
  185. // sys_wait4(g_ts_maintain_pid, (int __user *)&status, 0, NULL);
  186. pthread_join(g_ts_maintain, NULL);
  187. g_ts_maintain = 0;
  188. }
  189. return 0;
  190. }
  191. #endif
  192. #ifdef LINUX_KERNEL_APP
  193. void net_maintain_zombie(void)
  194. {
  195. int status;
  196. if(g_mt_zombie_flag)
  197. {
  198. // 关闭端口服务
  199. net_debug_exit();
  200. close_inet_port();
  201. if(g_ts_maintain != NULL && g_mt_zombie_flag == 1)
  202. {
  203. sys_wait4(g_ts_maintain_pid, (int __user *)&status, 0, NULL);
  204. g_ts_maintain =NULL;
  205. }
  206. g_mt_zombie_flag = 0;
  207. }
  208. }
  209. #else
  210. void net_maintain_zombie(void)
  211. {
  212. //int status;
  213. if(g_mt_zombie_flag)
  214. {
  215. // 关闭端口服务
  216. net_debug_exit();
  217. close_inet_port();
  218. if(g_ts_maintain && g_mt_zombie_flag == 1)
  219. {
  220. // sys_wait4(g_ts_maintain_pid, (int __user *)&status, 0, NULL);
  221. pthread_join(g_ts_maintain, NULL);
  222. g_ts_maintain = 0;
  223. }
  224. g_mt_zombie_flag = 0;
  225. }
  226. }
  227. #endif
  228. int net_maintain_send(unsigned char *buf,int len)
  229. {
  230. if(g_maintain_client == RT_SOCKET_ERR)
  231. {
  232. return 0;
  233. }
  234. return rt_send(g_maintain_client,buf,len,0);
  235. }
  236. #ifdef CPU_FUXI
  237. void open_inet_port(void)
  238. {
  239. // char *envp[] = { NULL };
  240. // char *cmd[] = {"/etc/init.d/inetd", "start", NULL};
  241. if(port_openflag)
  242. {
  243. rt_printf("open_inet_port =%d fail, return!!\r\n",port_openflag);
  244. return;
  245. }
  246. port_openflag = 1;
  247. //调用shell脚本,打开对应端口
  248. system("/etc/init.d/S70vsftpd start");
  249. // call_usermodehelper("/etc/init.d/inetd", cmd, envp, UMH_NO_WAIT);
  250. }
  251. #else
  252. void open_inet_port(void)
  253. {
  254. #if 0
  255. char *envp[] = { NULL };
  256. char *cmd[] = {"/usr/sbin/inetd", "-q", g_port_server_sel, NULL};
  257. int ret ;
  258. if(port_openflag)
  259. {
  260. return;
  261. }
  262. port_openflag = 1;
  263. ret = get_mt_port_proc( );
  264. if(ret==NET_MT_PORT_PROC_2)
  265. {
  266. strcpy(g_port_server_sel, "127");
  267. }
  268. else
  269. {
  270. strcpy(g_port_server_sel, "128");
  271. }
  272. //调用shell脚本,打开对应端口
  273. call_usermodehelper("/usr/sbin/inetd", cmd, envp, UMH_WAIT_PROC);
  274. #else
  275. char *envp[] = { NULL };
  276. char *cmd[] = {"/usr/sbin/vsftpd", "/etc/vsftpd.conf &", NULL};
  277. if(port_openflag)
  278. {
  279. return;
  280. }
  281. port_openflag = 1;
  282. //调用shell脚本,打开对应端口
  283. call_usermodehelper("/usr/sbin/vsftpd", cmd, envp, UMH_WAIT_PROC);
  284. #endif
  285. }
  286. #endif
  287. #ifdef CPU_FUXI
  288. void close_inet_port(void)
  289. {
  290. char *envp[] = { NULL };
  291. char *cmd0[] = {"/usr/bin/killall", "telnetd", NULL}; // sunxi 20220727 added
  292. char *cmd1[] = {"/usr/bin/killall", "vsftpd", NULL}; // sunxi 20220822 added
  293. // char *cmd[] = {"/etc/init.d/inetd", "stop", NULL};
  294. if(!port_openflag)
  295. {
  296. return;
  297. }
  298. port_openflag = 0;
  299. //调用shell脚本,关闭对应端口
  300. call_usermodehelper("/usr/bin/killall", cmd0, envp, UMH_WAIT_PROC); // sunxi 20220727 added
  301. call_usermodehelper("/usr/bin/killall", cmd1, envp, UMH_WAIT_PROC); // sunxi 20220822 added
  302. // call_usermodehelper("/etc/init.d/inetd", cmd, envp, UMH_WAIT_PROC);
  303. }
  304. #else
  305. void close_inet_port(void)
  306. {
  307. char *envp[] = { NULL };
  308. char *cmd0[] = {"/usr/bin/killall", "telnetd", NULL}; // sunxi 20220727 added
  309. char *cmd1[] = {"/usr/bin/killall", "vsftpd", NULL}; // sunxi 20220822 added
  310. char *cmd[] = {"/etc/rc.d/init.d/inetd", "stop", NULL};
  311. if(!port_openflag)
  312. {
  313. return;
  314. }
  315. port_openflag = 0;
  316. //调用shell脚本,关闭对应端口
  317. call_usermodehelper("/usr/bin/killall", cmd0, envp, UMH_WAIT_PROC); // sunxi 20220727 added
  318. call_usermodehelper("/usr/bin/killall", cmd1, envp, UMH_WAIT_PROC); // sunxi 20220822 added
  319. call_usermodehelper("/etc/rc.d/init.d/inetd", cmd, envp, UMH_WAIT_PROC);
  320. }
  321. #endif
  322. //得到ENV_MT_PORT_ON的处理方法
  323. // 0:表示应用启动时关闭除2404外的所有服务端口.如果维护工具连接,在所有网络上启动需要的服务端口,
  324. // 保证现场运行的装置可以通过主站升级程序。出货用。
  325. // 1:表示任何时候都不关闭任何服务端口。特殊情况用。
  326. // 2:表示应用启动时关闭除2404外的所有服务端口.如果维护工具连接,只在网络3上启动需要的服务端口,
  327. // 这样在正常连主站的网络扫描不到任何端口,以保证测试不问题。测试用。
  328. int get_mt_port_proc(void)
  329. {
  330. char *mt_port = env_get_info(ENV_MT_PORT_ON);
  331. if(!mt_port)
  332. {
  333. return NET_MT_PORT_PROC_0;
  334. }
  335. if(strcmp(mt_port, "1")==0)//表示应用启动时不关闭服务端口.如果启动服务端口,可以在任意网口上启动
  336. {
  337. return NET_MT_PORT_PROC_1;
  338. }
  339. else if(strcmp(mt_port, "2")==0)//应用启动时关闭服务端口.如果启动服务端口,只在最后一个网口上启动
  340. {
  341. return NET_MT_PORT_PROC_2;
  342. }
  343. return NET_MT_PORT_PROC_0;
  344. }
  345. /*------------------------------ 内部函数 -------------------------------------
  346. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  347. */
  348. int _net_maintain_thread(void * unused)
  349. {
  350. struct sockaddr_in server_addr;
  351. struct sockaddr_in client_addr;
  352. #ifndef LINUX_KERNEL_APP
  353. struct timeval timeout;
  354. #endif
  355. struct linger ling;
  356. SOCKET maintain_server,tmp_sock;
  357. int sin_size;
  358. int i,len,ret;
  359. unsigned char *ip;
  360. #ifdef LINUX_KERNEL_APP
  361. unsigned int recv_timeout;
  362. unsigned int link_timeout = dTCounter;
  363. #else
  364. int recv_timeout;
  365. int link_timeout = 0;
  366. #endif
  367. unsigned int ip_server;
  368. prctl(PR_SET_NAME, "_net_maintain_t");
  369. while(1)
  370. {
  371. g_ip_net_maintain = 0; //清零
  372. // 1、建立socket并侦听
  373. // 服务器端开始建立socket描述符
  374. #ifdef LINUX_KERNEL_APP
  375. maintain_server = rt_socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
  376. #else
  377. maintain_server = rt_socket(AF_INET, SOCK_STREAM, 0);
  378. #endif
  379. if (maintain_server == RT_SOCKET_ERR)
  380. {
  381. RT_PRINTF_POSITION();
  382. g_ts_maintain = NULL;
  383. return -1;
  384. }
  385. // 服务器端填充sockaddr结构
  386. memset (&server_addr, 0, sizeof (struct sockaddr_in));
  387. server_addr.sin_family = AF_INET;
  388. if(get_mt_port_proc()==NET_MT_PORT_PROC_2)
  389. {
  390. if(rt_if_ip_get2(0, 3, (unsigned char *)&ip_server)==0)
  391. {
  392. server_addr.sin_addr.s_addr = htonl (ip_server);
  393. }
  394. else
  395. {
  396. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  397. }
  398. }
  399. else
  400. {
  401. server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  402. }
  403. server_addr.sin_port = htons (NET_MAINTAIN_PORT);
  404. // 捆绑sockfd描述符
  405. ret = rt_bind (maintain_server, (struct sockaddr *)(&server_addr), sizeof (struct sockaddr));
  406. if (ret < 0)
  407. {
  408. RT_PRINTF_POSITION();
  409. rt_socket_close (maintain_server);
  410. g_ts_maintain = NULL;
  411. return -2;
  412. }
  413. #ifndef LINUX_KERNEL_APP
  414. // 设置接收超时
  415. timeout.tv_sec = 0;
  416. timeout.tv_usec = 500000;
  417. rt_setsockopt(maintain_server,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout ,sizeof(struct timeval));
  418. #endif
  419. // 设置关闭延时
  420. ling.l_onoff = 1;
  421. ling.l_linger = 0;
  422. rt_setsockopt(maintain_server,SOL_SOCKET,SO_LINGER,(char *)&ling ,sizeof(struct linger));
  423. // 监听sockfd描述符
  424. ret = rt_listen (maintain_server, 1);
  425. if (ret < 0)
  426. {
  427. RT_PRINTF_POSITION();
  428. rt_socket_close (maintain_server);
  429. g_ts_maintain = NULL;
  430. return -3;
  431. }
  432. g_maintain_client = RT_SOCKET_ACCEPT_RST;
  433. // 2、接受外部链接
  434. #ifdef RT_SOCKET_FD
  435. while(g_maintain_client < 0)
  436. #else
  437. while(g_maintain_client == RT_SOCKET_ACCEPT_RST)
  438. #endif
  439. {
  440. msleep(100);
  441. // 服务器阻塞,直到客户程序建立连接
  442. sin_size = sizeof (struct sockaddr_in);
  443. g_maintain_client = rt_accept (maintain_server, (struct sockaddr*)(&client_addr), &sin_size);
  444. // 检查是否退出
  445. if(g_net_maintain_exit_flag)
  446. {
  447. // 关闭客户端
  448. if(g_maintain_client)
  449. {
  450. tmp_sock = g_maintain_client;
  451. g_maintain_client = RT_SOCKET_ERR;
  452. rt_socket_close (tmp_sock);
  453. }
  454. // 关闭服务器
  455. rt_socket_close (maintain_server);
  456. g_net_maintain_exit_flag = 0;
  457. return 0;
  458. }
  459. //IP已经修改要关闭SOCKET
  460. if(g_net_miantain_sock_flag == NET_SOCKET_CLOSING)
  461. {
  462. //关闭客户端
  463. if(g_maintain_client != RT_SOCKET_ERR)
  464. {
  465. tmp_sock = g_maintain_client;
  466. g_maintain_client = RT_SOCKET_ERR;
  467. rt_socket_close (tmp_sock);
  468. }
  469. // 关闭服务器
  470. rt_socket_close (maintain_server);
  471. //置已经关闭标志
  472. g_net_miantain_sock_flag = NET_SOCKET_CLOSED;
  473. //等待IP修改完成
  474. while(g_net_miantain_sock_flag != NET_SOCKET_REINIT)
  475. {
  476. msleep(100);
  477. }
  478. //置为初始化
  479. g_net_miantain_sock_flag = NET_SOCKET_INIT;
  480. goto NET_END;
  481. }
  482. }
  483. // 3、关闭侦听socket,避免多个外部连接
  484. rt_socket_close(maintain_server);
  485. ip = (unsigned char *)&client_addr.sin_addr.s_addr;
  486. rt_printf("maintain client connect(ip=%d.%d.%d.%d)!\r\n",ip[0],ip[1],ip[2],ip[3]);
  487. {
  488. char buf[64];
  489. char log_info[128];
  490. sprintf(buf,"6008端口连接(%d#网络:IP=%d.%d.%d.%d)!\r\n", set_get_network_id_from_socket(g_maintain_client)+1, ip[0],ip[1],ip[2],ip[3]);
  491. log_str_time(LOG_OPERATE,buf,0,1);
  492. sprintf(log_info,"6008 port connection(%d#net:IP=%d.%d.%d.%d)",set_get_network_id_from_socket(g_maintain_client)+1, ip[0],ip[1],ip[2],ip[3]);
  493. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,log_info,1);
  494. }
  495. //记录客户端地址
  496. memcpy(&g_ip_net_maintain, ip, 4);
  497. // 4、客户端已连接,处理客户端命令
  498. #ifdef LINUX_KERNEL_APP
  499. recv_timeout=dTCounter;
  500. #else
  501. recv_timeout=0;
  502. #endif
  503. while(1)
  504. {
  505. #ifdef LINUX_KERNEL_APP
  506. msleep(2);//noted by sunxi: 20221212 设为非阻塞型
  507. len = rt_recv (g_maintain_client, g_net_miantain_buf, NET_RECV_MAX, MSG_DONTWAIT);
  508. #else
  509. len = rt_recv (g_maintain_client, g_net_miantain_buf, NET_RECV_MAX, 0);
  510. #endif
  511. // 检查是否退出
  512. if(g_net_maintain_exit_flag)
  513. {
  514. // 关闭客户端
  515. tmp_sock = g_maintain_client;
  516. g_maintain_client = RT_SOCKET_ERR;
  517. rt_socket_close (tmp_sock);
  518. g_net_maintain_exit_flag = 0;
  519. return 0;
  520. }
  521. //IP已经修改要关闭SOCKET
  522. if(g_net_miantain_sock_flag == NET_SOCKET_CLOSING)
  523. {
  524. // 关闭客户端
  525. tmp_sock = g_maintain_client;
  526. g_maintain_client = RT_SOCKET_ERR;
  527. rt_socket_close (tmp_sock);
  528. //置已经关闭标志
  529. g_net_miantain_sock_flag = NET_SOCKET_CLOSED;
  530. //等待IP修改完成
  531. while(g_net_miantain_sock_flag != NET_SOCKET_REINIT)
  532. {
  533. msleep(100);
  534. }
  535. //置为初始化
  536. g_net_miantain_sock_flag = NET_SOCKET_INIT;
  537. goto NET_END;
  538. }
  539. #ifdef CPU_FUXI
  540. if((len == -EAGAIN)||(len==-1))//noted by sunxi: 这里要加-1, 不然连接不上,可能与上面的rt_recv有关
  541. #else
  542. if(len == -EAGAIN)
  543. #endif
  544. {
  545. if(rt_get_net_linkstatus(rt_get_netcard_id_from_socket(g_maintain_client))==1)
  546. {
  547. #ifdef LINUX_KERNEL_APP
  548. if((dTCounter - link_timeout)>RT_LINK_TIMEOUT*T_1s) //500ms超时
  549. #else
  550. link_timeout++;
  551. if(link_timeout>RT_LINK_TIMEOUT*2) //500ms超时
  552. #endif
  553. {
  554. rt_printf("%s: link down\n",__FUNCTION__);
  555. #ifdef LINUX_KERNEL_APP
  556. link_timeout = dTCounter;
  557. #else
  558. link_timeout = 0;
  559. #endif
  560. break;
  561. }
  562. }
  563. else
  564. {
  565. #ifdef LINUX_KERNEL_APP
  566. link_timeout = dTCounter;
  567. #else
  568. link_timeout = 0;
  569. #endif
  570. }
  571. // 超时
  572. #ifdef LINUX_KERNEL_APP
  573. if((dTCounter - recv_timeout)>120*T_1s) // 超时2分钟,端口未收到数据,关闭端口
  574. #else
  575. recv_timeout++;
  576. if(recv_timeout>240) // 超时2分钟,端口未收到数据,关闭端口
  577. #endif
  578. {
  579. rt_printf ("net_maintain_thread:timeout\r\n");
  580. break;
  581. }
  582. continue;
  583. }
  584. else if (len <= 0)
  585. {
  586. //调用recv时,如果返回0,则表示对端关闭;返回负数,表示出错
  587. rt_printf ("net_maintain_thread:peer close(ret=%d).\r\n",len);
  588. msleep(100);
  589. break;
  590. }
  591. // 接收数据
  592. #ifdef LINUX_KERNEL_APP
  593. recv_timeout = dTCounter;
  594. link_timeout = dTCounter;
  595. #else
  596. recv_timeout=0;
  597. link_timeout = 0;
  598. #endif
  599. for(i=0;i<len;i++)
  600. {
  601. Maintain_Recv(g_net_miantain_buf[i]);
  602. }
  603. }
  604. // 关闭客户端socket
  605. tmp_sock = g_maintain_client;
  606. g_maintain_client = RT_SOCKET_ERR;
  607. {
  608. char buf[64];
  609. char log_info[128];
  610. sprintf(buf,"6008端口关闭(%d#网络:IP=%d.%d.%d.%d)!\r\n", set_get_network_id_from_socket(tmp_sock)+1, ip[0],ip[1],ip[2],ip[3]);
  611. log_str_time(LOG_OPERATE,buf,0,0);
  612. sprintf(log_info,"6008 port close(%d#net:IP=%d.%d.%d.%d)",set_get_network_id_from_socket(tmp_sock)+1, ip[0],ip[1],ip[2],ip[3]);
  613. load_hs_log_rcd(TYPE_CHNL_LINK,true,NULL,log_info,0);
  614. }
  615. rt_socket_close (tmp_sock);
  616. NET_END:
  617. // 如果维护端口打开环境变量不存在,直接退出
  618. if(get_mt_port_proc() != 1)
  619. {
  620. // 设置僵死标志,让主循环回收
  621. g_mt_zombie_flag = 1;
  622. break;
  623. }
  624. else
  625. {
  626. g_mt_zombie_flag = 0;
  627. }
  628. }
  629. return 0;
  630. }
  631. /*------------------------------ 测试函数 -------------------------------------
  632. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  633. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  634. */
  635. /*------------------------------ 文件结束 -------------------------------------
  636. */