背景:对于大公司的同步,可能会采用zoomkeeper作肿裁加agent下发shell命令实现,而对于小公司,大都采用linux下有一个叫rsync这样的加上notice作同步。
如何杀死rsync的同步进程d:



阅读全文
背景:群里说到,没有注意,自己升级了下自己的vps服务器,后来公司要求也升级下线上服务器,才知事情严重,为过好国庆升级是必要 的,听说苹果系统说自己系统尽管也用这个bash,如果没有设置高级什么的,不存在此漏洞。

Bash 远程任意代码执行安全漏洞(最严重漏洞)
US-CERT 意识到 Bash 存在一个安全的漏洞,该漏洞直接影响基于 Unix 的系统(如 Linux、OS X 等)。该漏洞将导致远程攻击者在受影响的系统上执行任意代码。
US-CERT 建议用户和管理员重新检查这篇红帽的安全博客。更多的详情只能参考相应 Linux 发行商以获取相应补丁。
你可以使用如下命令来检查系统存在此漏洞:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
受影响的系统包括:
CentOS
Debian
Redhat
Ubuntu
红帽系可通过更新 bash 并重启系统来解决这个问题:
# yum update bash
或者:
# yum update bash-4.1.2-15.el6_5.1
此举只是更新了 bash 包,还需要重启系统才能生效。

Ubuntu 用户可以通过如下命令打补丁,无需重启:
apt-get update
apt-get install bash

______________________________
[root@jackxiang ~]# rpm -qa|grep bash
bash-4.1.2-15.el6_5.1.x86_64

背景:想加个内存,Mysql服务器上的内存不够了,就算可以插(插槽都有,现在是4条4G内存,还有空闲八个槽。),不知道兼不兼容,否则不稳定的,不兼容的话,死的更惨,这个不一定了,停产了,就没有办法了。怎么办?得看内存的品牌及型号。
[root@jackxiang ~]# rpm -qa|grep dmidecode
dmidecode-2.11-2.el6.x86_64
[root@jackxiang ~]# dmidecode    
查看服务器型号、序列号:
[root@jackxiang ~]# dmidecode|grep "System Information" -A9|egrep  "Manufacturer|Product|Serial"  
        Manufacturer: VMware, Inc.
        Product Name: VMware Virtual Platform
        Serial Number: VMware-42 18 c8 32 77 c6 ec 16-3f 31 94 e9 d0 34 a6 ac
Linux 查看内存的插槽数,已经使用多少插槽.每条内存多大:
[root@jackxiang ~]# dmidecode|grep -A5 "Memory Device"|grep Size|grep -v Range
        Size: 4096 MB
        Size: 2048 MB
        Size: No Module Installed
        Size: No Module Installed

Linux 查看内存的频率:
[root@localhost htdocs]# dmidecode|grep -A16 "Memory Device"|grep 'Speed'
        Speed: 667 MHz (1.5 ns)
        Speed: 667 MHz (1.5 ns)
        Speed: 667 MHz (1.5 ns)
        Speed: 667 MHz (1.5 ns)
        Speed: Unknown

在linux查看内存型号的命令:
dmidecode -t memory

查看主板型号:
dmidecode |grep -A16 "System Information$"

内存槽及内存条:
dmidecode |grep -A16 "Memory Device$"

硬盘:
fdisk -l
smartctl -a /dev/sda

网卡:
mii-tool
————————————————————————————————————————————————————
dmidecode|grep -P 'Maximum\s+Capacity'    //最大支持几G内存
# cat  /proc/cpuinfo //查看cpu个数与频率
# dmidecode  |grep  "Product Name"  //查看服务器品牌和型号
# dmidecode|grep -P -A5 "Memory\s+Device"|grep Size|grep -v Range       //总共几个插槽,已使用几个插槽
Size: 1024 MB       //此插槽有1根1G内存
Size: 1024 MB       //此插槽有1根1G内存
Size: 1024 MB       //此插槽有1根1G内存
Size: 1024 MB       //此插槽有1根1G内存
Size: No Module Installed       //此插槽未使用
Size: No Module Installed       //此插槽未使用

# dmidecode -t 17        //数字17是dmidecode的参数,本文最后有其他数字参数
dmidecode 2.7
SMBIOS 2.4 present.
Handle 0x0015, DMI type 17, 27 bytes.
Memory Device
  Array Handle: 0x0013
  Error Information Handle: Not Provided
  Total Width: 72 bits
  Data Width: 64 bits
  Size: 2048 MB 【插槽1有1条2GB内存】
  Form Factor: DIMM
  Set: None
  Locator: DIMM00
  Bank Locator: BANK
  Type: Other
  Type Detail: Other
  Speed: 667 MHz (1.5 ns)
  Manufacturer:
  Serial Number: BZACSKZ001
  Asset Tag: RAM82
  Part Number: MT9HTF6472FY-53EA2
Handle 0x0017, DMI type 17, 27 bytes.
Memory Device
  Array Handle: 0x0013
  Error Information Handle: Not Provided
  Total Width: 72 bits
  Data Width: 64 bits
  Size: 2048 MB 【插槽2有1条2GB内存】
  Form Factor: DIMM
  Set: None
  Locator: DIMM10
  Bank Locator: BANK
  Type: Other
  Type Detail: Other
  Speed: 667 MHz (1.5 ns)
  Manufacturer:
  Serial Number: BZACSKZ001
  Asset Tag: RAM83
  Part Number: MT9HTF6472FY-53EA2
Handle 0x0019, DMI type 17, 27 bytes.
Memory Device
  Array Handle: 0x0013
  Error Information Handle: Not Provided
  Total Width: 72 bits
  Data Width: 64 bits
  Size: 2048 MB 【插槽3有1条2GB内存】
  Form Factor: DIMM
  Set: None
  Locator: DIMM20
  Bank Locator: BANK
  Type: Other
  Type Detail: Other
  Speed: 667 MHz (1.5 ns)
  Manufacturer:
  Serial Number: BZACSKZ001
  Asset Tag: RAM84
  Part Number: MT9HTF6472FY-53EA2
Handle 0x001B, DMI type 17, 27 bytes.
Memory Device
  Array Handle: 0x0013
  Error Information Handle: Not Provided
  Total Width: 72 bits
  Data Width: 64 bits
  Size: 2048 MB 【插槽4有1条2GB内存】
  Form Factor: DIMM
  Set: None
  Locator: DIMM30
  Bank Locator: BANK
  Type: Other
  Type Detail: Other
  Speed: 667 MHz (1.5 ns)
  Manufacturer:
  Serial Number: BZACSKZ001
  Asset Tag: RAM85
  Part Number: MT9HTF6472FY-53EA2

实践来源:
http://www.jbxue.com/LINUXjishu/10053.html
http://www.linuxsir.org/bbs/thread309696.html
http://xclinux.diandian.com/post/2013-04-16/40049844350
FreeBSD 在 RPi 2上的用户名和密码:
默认的密码是 freebsd/freebsd 和 root/root

FreeBSD系统中无线网络连接无线网卡:
http://www.111cn.net/sys/freebsd/59534.htm
本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2015-12/126724.htm

FreeBSD 11-CURRENT on Raspberry Pi Apache 2.4/MySQL 5.6/PHP 5.6, 如何在树莓派 2B 上安装 FreeBSD及网络配置:
http://jackxiang.com/post/8455/

定制Raspberry Pi网站:
http://www.embest-tech.cn/pi-customization/

FreeBSD has supported Raspberry Pi since November 2012, and the current production version (FreeBSD 10) is available as a pre-built image which can be copied onto a memory card.

Download the latest image file from the official FreeBSD ARM page. This page has images for other ARM-based boards like the Beaglebone and the Pandaboard. You need to download an image for the “RPI-B”: for example “FreeBSD-10.0-RELEASE-arm-armv6-RPI-B-20140131-r260789.img.bz2”
摘自 : https://www.maketecheasier.com/freebsd-on-raspberry-pi/

DRAM:  944 MiB
WARNING: Caches not enabled
RPI 2 Model B
MMC:   bcm2835_sdhci: 0
reading uboot.env

修改raspberry pi上安装的freebsd可用内存大小:
http://blog.sina.com.cn/s/blog_a0aacb430101mj69.html


background:Freebsd是真正的Unix血统的Os,其稳定性是顶级的,真正的坚如磐石。在树莓派下也有ARM版本了,最新稳定版本:
ftp://ftp6.freebsd.org/pub/FreeBSD/snapshots/arm/armv6/ISO-IMAGES/10.0//FreeBSD-10.0-STABLE-arm-armv6-RPI-B-20140822-r270340.img.bz2  
CheckSum:
ftp://ftp6.freebsd.org/pub/FreeBSD/snapshots/arm/armv6/ISO-IMAGES/10.0/CHECKSUM.SHA256-10.0-STABLE-arm-armv6-RPI-B-20140822-r270340




三、FreeBSD 11 on Raspberri pi 2(树莓派 2 安装 FreeBSD 11)  :
A note for my own installation.(树莓派 2 安装 FreeBSD 11)
I tried compiling the FreeBSD 11 by myself, but I found there are ready-to-use systems here.
1. Identify your SD card:
# df -h
you will see the result as
de>/dev/mmcblk0p1de> or de>/dev/sdb1de> or something is different from /sda.

2. Unmount the card
# umount de>/dev/mmcblk0p1de> or de>/dev/sdb1de>

3. Copy your image file to the card, (Very important! DO NOT add the partition number p1 or 1, just use the whole card de>mmcblk0 or sdbde>)
# dd bs=4M if=your-freebsd-rpi2-image.img of=/dev/de>mmcblk0de>

4. First boot
After the raspberry pi 2 is powered on, you need login using user name : root, you need also set the password
# passwd

5.Increase swap space
# dd if=/dev/zero of=/usr/swap0 bs=1m count=1024
# chmod 0600 /usr/swap0
# echo 'md99 none swap sw,file=/usr/swap0 0 0' >> /etc/fstab
# swapon -aq

*系统目前很卡,还是不建议安装。感觉Raspbian 还是最流畅的。
来自:http://rhuta.blog.163.com/blog/static/17757006220154129421478/
阅读全文
Q: 我正在写一个unix server程序,不是daemon,经常需要在命令行上重启它,绝大多数时候工作正常,但是某些时候会报告"bind: address in use",于是重启失败。
A: Andrew Gierth
server程序总是应该在调用bind()之前设置SO_REUSEADDR套接字选项。至于TIME_WAIT状态,你无法避免,那是TCP协议的一部分。阅读全文
这个相当于windows里的启动项
vi  /etc/rc.d/rc.local
按i
然后把你的命令贴进去 ,一行一条命令
/bin/bash /usr/local/scripts/autoStartNginxEnterSSLKey.sh
然后按 esc
再 :wq 保存  注意前面有两点的冒号
下次重启的时候这个就会自动执行你添加的命令。



vi /usr/local/scripts/autoStartNginxEnterSSLKey.sh


./startNginx.sh
cat ./startNginx.sh
/usr/local/nginx/sbin/nginx

来自:http://zhidao.baidu.com/link?url=D7tZLZFqg7LODR60qIkvAeoSk-ocjBWgLppmxkHh_gSxH3AvOkZ_S9SxTj-C50espCswUiYZRK9F4JYi2nVC8K
yum install traceroute -y
阅读全文
  最近一直在看《Linux程序设计(第3版)》,照着书上的代码原封不动地敲上去,编译后就出现了à警告:隐式声明与内建函数’exit’不兼容。
警告:隐式声明与内建函数‘exit’不兼容



       原因其实很简单了,没有把stdlib.h包含进来,加上就没问题了。后来google搜索的时候发现网上很多人有这个问题,今天来记下这个问题的解决方案。

以此类推,编译后出现警告:隐式声明与内建函数’XXX’不兼容的问题所在都是因为没有包含相应的头文件,加上就OK!

来自:http://blog.csdn.net/monkey_d_meng/article/details/5565667
背景:有时在重启时出现nginx启动比sshd还快,导致加了ssh启动nginx要密码(后来去了),卡在那儿起不来,作为vps,打电话太麻烦了,于是否,能不定定个顺序,可能好一些。
  我们知道,在Linux系统中,系统服务的启动脚本一般放在/etc/init.d目录下。不同的开机模式,则分别对应到/etc/rcx.d目录下。其实/etc/rcx.d上的文件,一般都是链接到/etc/init.d目录下的对应文件的。我们还知道,/etc/rcx.d下的文件名,是以S+数字或K+数字打头的,这里的S表示启动,K表示关闭,数值其后面的数值则表示服务启动或服务退出时的次序。那么,这些数值是怎样来的呢?是不是需要在/etc/rcx.d下去修改文件名呢?答案是否定的。那应该怎么做呢?

        打开/etc/init.d下的脚本,查找类似下面的一句:

        #chkconfig: 2345 64 36

        这里的64,就是启动的顺序值,36则是退出的顺序值,如果需要改变顺序,就在这里改。然后执行下面的命令:

        #chkconfig --del servicename

        #chkconfig --add servicename

        #chkconfig servicename on



        servicename对应您的服务名称。

来自:http://blog.csdn.net/yetyongjin/article/details/7050068

实践如下:
vi /var/log/boot.log
Starting mcelog daemon
^[[60G[^[[0;32m  OK  ^[[0;39m]^MStarting php-fpm  done
Starting nginx...  done
Starting sshd: ^[[60G[^[[0;32m  OK  ^[[0;39m]^M
Starting xinetd: ^[[60G[^[[0;32m  OK  ^[[0;39m]^M
Starting MySQL^[[60G[^[[0;32m  OK  ^[[0;39m]^M

vi /etc/init.d/sshd
# chkconfig: 2345 55 25
vi /etc/init.d/nginx
# chkconfig: 2345 55 25
于是作下调整如下:
vi /etc/init.d/sshd
# chkconfig: 2345 5425
linux在启动过程中都干了些什么,都有哪些程序被调用,是不是看系统的启动日志就可以?启动日志是哪个文件?
终端运行下就知道了
dmesg | less
启动的文件日志
less /var/log/boot.log
其他日至都在/var/log里

less /var/log/boot.log
less /var/log/dmesg

http://bbs.chinaunix.net/thread-2140832-1-1.html
Centos7.7安装vncserver虚拟网络控制台:
https://www.linuxprobe.com/centos7-virtual-network-console.html
sudo systemctl enable vncserver@:2
Created symlink from /etc/systemd/system/multi-user.target.wants/vncserver@:2.service to /etc/systemd/system/vncserver@:2.service.

server already running on display :1
/bin/startxfce4: X server already running on display :1

重启服务时这里可能会提示 A VNC server is already running as :1 [FAILED]的错误,解决方法见下。
vncserver -kill :1
Killing Xvnc process ID 3654,VNCServer使用方法
[root@localhost ~]# vncserver :1    启动:1
[root@localhost ~]# vncserver :2    启动:2
[root@localhost ~]# ps -ef|grep -i xvnc   查看已启动的server
[root@localhost ~]# vncserver -kill :1    杀死:1


解決Windows 7 的VNC connection reset by peer 10054錯誤:
當Windows 7 更新到某個程度,原本可以正常運作的VNC連接就會突然出現VNC connection reset by peer 10054錯誤,然後就無法用VNC Viewer連上這台Windows 7 電腦。 無論是使用哪種VNC Server,如TightVNC或RealVNC都無法修正此問題。

查Google之後,發現只有Windows 7會有這種「相容性」問題,其他版本的Windows就不會,因此,一個簡單的解決辦法就是將VNC的Server執行程式改成相容模式執行。以RealVNC Server為例,首先找到VNC Server程式的位置(通常是C:\Program Files\RealVNC\VNC4),右鍵點選Server程式(winvnc4.exe)->內容->相容性->勾選以相容模式執行這個程式,選擇不是Windows 7的其他選項。最後,到電腦管理中的「服務」,重新啟動VNC Server就可以連接了。
来自:http://eportfolio.lib.ksu.edu.tw/~T093000298/blog?node=000000209
解决vncserver卡死,报错connection reset by peer (10054)
在连接慢速网络环境到vncserver服务器的时候,经常动不动就失去响应。过一会而vncview提示连接被远程断开,解决的办法有2个:
1. vnc view option菜单,选择inputs, 勾选Rate-limit mouse move events,这样可以节省带宽,提升一些响应速度
2. Coloure Level 选择256色,不要用full color,最新版本的VncViewer,这个叫Picture Quality 选:Low,Download Url:https://www.realvnc.com/download/file/viewer.files/VNC-Viewer-6.17.1113-Windows-32bit.exe

以上两条一起用,上面颜色没看到,勾选Rate-limit mouse move events是可以的。
3.把VPC的分辨率调低一点:#vncserver :1 -geometry 1024x768
vncserver :1 -geometry 800x600   ,以上三条后,在公司 访问就Ok了,不再出现错误了,感觉还是带宽不够。

1)stop vnc server from linux terminal:
~/stopvncserver.sh


new Test port always 5902,like this is ok:


2)start vnc server from linux terminal:
~/startvncserver.sh


真实实践:
一)实践没有问题的脚本:
cat /home/irdcops/shell/vncsvr/startvncsvr.sh
cat /home/ops/shell/vncsvr/startvncsvr.sh





二)vnc的端口情况(如何修改linux里的VNC的默认端口5901):


三)Iptable得放开这个端口,否则连接不上:

总论详细文章Url:http://www.tuicool.com/articles/zQrQNz


四)出现空白桌面,啥也没有,只看到浏览器(没安装浏览器也就啥也没有),没有xfe桌面的情况解决,实践OK:
cat /root/.vnc/xstartup


五)出现VNC:1本来不存在,缺提示存在的情况:
vncserver :1 -geometry 1024x768
A VNC server is already running as :1
并不是真的在运行,其原因是vncconfig进程在,于是干死重来:
ps -ef|grep vnc
root     26027     1  0 10:23 pts/4    00:00:00 vncconfig -iconic
kill -9 26027



六)重启的SHell:
/home/irdcops/shell/vncsvr/startvncsvr.sh
/home/ops/shell/vncsvr/startvncsvr.sh


七)定时Cron:
/home/irdcops/shell/vncsvr/startvncsvrcron.sh


问题依旧,vi +168 /usr/bin/vncserver:
162 # Find display number.
163 if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) {
164     $displayNumber = $1;
165     shift(@ARGV);
166     if (!&CheckDisplayNumber($displayNumber)) {
167         warn "A VNC server is already running as :$displayNumber\n";
168         $displayNumber = &GetDisplayNumber();                                
169     }
170 } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) {
171     &Usage();
172 } else {
173     $displayNumber = &GetDisplayNumber();
174 }

来自:https://github.com/TigerVNC/tigervnc/issues/531


六)VNCView端:
1.安装xwindow system
#yum groupinstall "X Window System"
2.安装GNOME
#yum groupinstall "Desktop"
3.安装中文支持
#yum groupinstall chinese-support
4.修改启动级别为5
#vi /etc/inittab
改default 5


七)加入systemctl:
# cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@:1.service
# vi /etc/systemd/system/vncserver@:1.service

systemctl daemon-reload
systemctl start vncserver@:1.service
systemctl enable vncserver@:1.service


八)tail -f /root/.vnc/levoo-bigdata_kafka-logstash_bj_rfls_10_10_0_100---解决失败!!!第二天解决成功@[实践OK]centos7 tigervnc 安装(非root用户的配置):https://jackxiang.com/post/10039/


\:1.log  /var/log/messages出现:XIO: fatal IO error 11 (Resource temporarily unavailable) on X server ":1"
centos 黑屏

查看日志 ~/.vnc/localhost.localdomain:0.log

/home/cake/.vnc/xstartup: line 27: xsetroot: command not found
/home/cake/.vnc/xstartup: line 28: xterm: command not found
/home/cake/.vnc/xstartup: line 29: twm: command not found
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server “:0″^M
after 141 requests (140 known processed) with 0 events remaining.^M

因为xsetroot/xterm/twm没有安装导致的。
CentOS7还不一样,得这样:https://github.com/plembo/onemoretech/wiki/20140824-twm-on-centos-7
实践如下:http://ftp.stu.edu.tw/Linux/CentOS/6/os/x86_64/Packages/xorg-x11-twm-1.0.3-5.1.el6.x86_64.rpm
rpm -ihv xorg-x11-twm-1.0.3-5.1.el6.x86_64.rpm
warning: xorg-x11-twm-1.0.3-5.1.el6.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:xorg-x11-twm-1:1.0.3-5.1.el6     ################################# [100%]
yum install xsetroot -y
Package xorg-x11-server-utils-7.7-20.el7.x86_64 already installed and latest version

于是使用yum安装:

yum install xsetroot -y
yum install xterm -y
yum install twm -y
kill掉vncserver进程,然后重新启动。来自:http://blog.51cto.com/zhangguangjun/2047209
vncserver -kill :1
vncserver :1

yum remove xterm -y
yum remove twm -y
yum remove xsetroot -y

来自:http://javacxn.blog.163.com/blog/static/1832776420139269545905/
======================================================================
Centos 6.4 安装 vnc:
安装:vnc
sudo yum install tigervnc  tigervnc-server
安完后先设置密码:
vncpasswd

启动:
vncserver :1
查看:
vncserver -list
杀死进程 :
vncserver -kill :1

远程连接:
用vnc软件,之后输入地址,如:mycclove.oicp.net:5901
119.10.6.23:5901

第二个屏则是:
119.10.6.23:2
1152x864

注意一点:需要在iptables中添加一条规则
-A INPUT -m state --state NEW -m tcp -p tcp --dport 5901 -j ACCEPT


========================
补充:
在windows下连接vnc有一个vncviewer软件,我在ubuntu中有现成的软件, 在CentOS中安装tigervnc后就出现了vncviewer的命令,就可以连接到服务器的vnc了。

连接之后黑屏:
把 用户下面的.vnc/目录下的xstartup添加777权限

来自:http://blog.sina.com.cn/s/blog_6c9d65a10101dyt0.html


设置VNC服务随系统启动自动加载
第一种方法:使用“ntsysv”命令启动图形化服务配置程序,在vncserver服务前加上星号,点击确定,配置完成。
第二种方法:使用“chkconfig”在命令行模式下进行操作,命令使用如下(预知chkconfig详细使用方法请自助式man一下)
[root@testdb ~]# chkconfig vncserver on
[root@testdb ~]# chkconfig --list vncserver
vncserver       0:off   1:off   2:on    3:on    4:on    5:on    6:off

摘自:http://blog.csdn.net/alvin969/article/details/6170884

附加:http://www.linuxidc.com/Linux/2012-11/73471.htm
1、which  vncserver  得到VNC Server运行脚本所在位置。
RHEL5默认为:/usr/bin/vncserver
2、使用vi打开vncserver
vi /usr/bin/vncserver
3、查找到默认的分辨率:1024X768,然后进行修改。该行在注释结束的第一段参数部分。根据实际使用显示器的分辨率,修改该参数。
4、修改完vncserver后,重新执行vncserver时即以新的分辨率开始。
5、验证:ps -ef | grep vnc,可以看到所显示的分辨率参数为修改后的参数。


Mac自带VNC Client,MacBook vnc使用方法:
由于有需要远程VNC的需要,苦苦寻找一款Mac上比较好使的VNC Client,结果经人指点,发现原来MacOS自带了VNC Client,只是没有在Launchpad中显示罢了。使用command+space 调出Spotlight搜索键入screen Sharing.app即可。

来自:https://notes.wanghao.work/2016-11-24-Mac%E8%87%AA%E5%B8%A6VNC-Client.html
来自姜源兄弟的博客:
http://blog.vetcafe.net/2013/12/
由于 KVM 支持全虚拟,所以可以在上面安装各类操作系统,再加上它跟FreeBSD的jail一样,属于系统自带的,我们可以用其搭建属于自己的开发展测试环境。阅读全文


【需求】
不影响服务器处理的前提下,检测客户端程序是否被强制终了。
【现状】
服务器端和客户端的Socket都设定了keepalive属性。
服务器端设定了探测次数等参数,客户端、服务器只是打开了keepalive机能
服务器端起了一个监视线程,利用select来检测socket是否被关闭。。。

下面这是我的一点肤浅理解。

1.关于keep alive

无论windows,还是linux,keepalive就三个参数:

    sk->keepalive_probes:探测次数
    sk->keepalive_time   探测的超时
    sk->keepalive_intvl 探测间隔

对 于一个已经建立的tcp连接。如果在keepalive_time时间内双方没有任何的数据包传输,则开启keepalive功能的一端将发送 eepalive数据包,若没有收到应答,则每隔keepalive_intvl时间再发送该数据包,发送keepalive_probes次。一直没有 收到应答,则发送rst包关闭连接。若收到应答,则将计时器清零。例如★:

    sk->keepalive_probes = 3;
    sk->keepalive_time   = 30;
    sk->keepalive_intvl = 1;

意 思就是说对于tcp连接,如果一直在socket上有数据来往就不会触发keepalive,但是如果30秒一直没有数据往来,则keep alive开始工作:发送探测包,受到响应则认为网络,是好的,结束探测;如果没有相应就每隔1秒发探测包,一共发送3次,3次后仍没有相应,
就 关闭连接,也就是从网络开始断到你的socket能够意识到网络异常,最多花33秒。但是如果没有设置keep alive,可能你在你的socket(阻塞性)的上面,接收: recv会一直阻塞不能返回,除非对端主动关闭连接,因为recv不知道socket断了。发送:取决于数据量的大小,只要底层协议站的buffer能放 下你的发送数据,应用程序级别的send就会一直成功返回。 直到buffer满,甚至buffer满了还要阻塞一段时间试图等待buffer空闲。所以你对send的返回值的检查根本检测不到失败。开启了keep alive功能,你直接通过发送接收的函数返回值就可以知道网络是否异常。设置的方法(应用层):

    int keepalive = 1; // 开启keepalive属性
    int keepidle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
    int keepinterval = 5; // 探测时发包的时间间隔为5 秒
    int keepcount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.
    setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive ));
    setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle ));
    setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval ));
    setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount ));

2.select和keep alive的关系

select 是为单个线程使用多个socket而设计的,跟检测连接无关,如果只是检测一个socket的话,没有必要使用select。开了keepalive机能 的话,每次调用recv或send时检查返回值,判断是否出错或为0.如果出错,再检查errno查资料,看哪个或哪几个错误号表示链接断了或不存在就可 以了。

另外,谁想定期检查连接状况,谁就启用keep alive。另一端可以不起,只是被动地对探测包进行响应,这种响应是tcp协议的基本要求,跟keep alive无关。并不需要客户端和服务器端都开启keep alive。

3.测试结果

按照例★的值在一端的socket上开启keep alive,然后阻塞在一个recv或者不停的send,这个时候拔了网线,测试从拔掉网线到recv/send返回失败的时间。

在linux kernel里头的测试发现,对于阻塞型的socket,当recv的时候,如果没有设置keep alive,即使网线拔掉或者ifdown,recv很长时间不会返回,最长达17分钟,虽然这个时间比linux的默认超时时间()短了很多。但是如果 设置了keep alive,基本都在keepalive_time +keepalive_probes*keepalive_intvl =33秒内返回错误。

但是对于循环不停send的socket,当拔掉网线后,会持续一段时间send返 回成功(0~10秒左右,取决 于发送数据的量),然后send阻塞,因为协议层的buffer满了,在等待buffer空闲,大概90秒左右后才会返回错误。由此看来,send的时 候,keep alive似乎没有起到作用,这个原因至今也不清楚。后来通过给send之前设置timer来解决的。


来自:http://blog.csdn.net/guomsh/article/details/8484207

linux下使用TCP存活(keepalive)定时器
一、什么是keepalive定时器?[1]
在一个空闲的(idle)TCP连接上,没有任何的数据流,许多TCP/IP的初学者都对此感到惊奇。也就是说,如果TCP连接两端没有任何一个进程在向对方发送数据,那么在这两个TCP模块之间没有任何的数据交换。你可能在其它的网络协议中发现有轮询(polling),但在TCP中它不存在。言外之意就是我们只要启动一个客户端进程,同服务器建立了TCP连接,不管你离开几小时,几天,几星期或是几个月,连接依旧存在。中间的路由器可能崩溃或者重启,电话线可能go down或者back up,只要连接两端的主机没有重启,连接依旧保持建立。
这就可以认为不管是客户端的还是服务器端的应用程序都没有应用程序级(application-level)的定时器来探测连接的不活动状态(inactivity),从而引起任何一个应用程序的终止。然而有的时候,服务器需要知道客户端主机是否已崩溃并且关闭,或者崩溃但重启。许多实现提供了存活定时器来完成这个任务。
存活定时器是一个包含争议的特征。许多人认为,即使需要这个特征,这种对对方的轮询也应该由应用程序来完成,而不是由TCP中实现。此外,如果两个终端系统之间的某个中间网络上有连接的暂时中断,那么存活选项(option)就能够引起两个进程间一个良好连接的终止。例如,如果正好在某个中间路由器崩溃、重启的时候发送存活探测,TCP就将会认为客户端主机已经崩溃,但事实并非如此。
存活(keepalive)并不是TCP规范的一部分。在Host Requirements RFC罗列有不使用它的三个理由:(1)在短暂的故障期间,它们可能引起一个良好连接(good connection)被释放(dropped),(2)它们消费了不必要的宽带,(3)在以数据包计费的互联网上它们(额外)花费金钱。然而,在许多的实现中提供了存活定时器。
一些服务器应用程序可能代表客户端占用资源,它们需要知道客户端主机是否崩溃。存活定时器可以为这些应用程序提供探测服务。Telnet服务器和Rlogin服务器的许多版本都默认提供存活选项。
个人计算机用户使用TCP/IP协议通过Telnet登录一台主机,这是能够说明需要使用存活定时器的一个常用例子。如果某个用户在使用结束时只是关掉了电源,而没有注销(log off),那么他就留下了一个半打开(half-open)的连接。在图18.16,我们看到如何在一个半打开连接上通过发送数据,得到一个复位(reset)返回,但那是在客户端,是由客户端发送的数据。如果客户端消失,留给了服务器端半打开的连接,并且服务器又在等待客户端的数据,那么等待将永远持续下去。存活特征的目的就是在服务器端检测这种半打开连接。

二、keepalive如何工作?[1]
在此描述中,我们称使用存活选项的那一段为服务器,另一端为客户端。也可以在客户端设置该选项,且没有不允许这样做的理由,但通常设置在服务器。如果连接两端都需要探测对方是否消失,那么就可以在两端同时设置(比如NFS)。
若在一个给定连接上,两小时之内无任何活动,服务器便向客户端发送一个探测段。(我们将在下面的例子中看到探测段的样子。)客户端主机必须是下列四种状态之一:
1) 客户端主机依旧活跃(up)运行,并且从服务器可到达。从客户端TCP的正常响应,服务器知道对方仍然活跃。服务器的TCP为接下来的两小时复位存活定时器,如果在这两个小时到期之前,连接上发生应用程序的通信,则定时器重新为往下的两小时复位,并且接着交换数据。
2) 客户端已经崩溃,或者已经关闭(down),或者正在重启过程中。在这两种情况下,它的TCP都不会响应。服务器没有收到对其发出探测的响应,并且在75秒之后超时。服务器将总共发送10个这样的探测,每个探测75秒。如果没有收到一个响应,它就认为客户端主机已经关闭并终止连接。
3) 客户端曾经崩溃,但已经重启。这种情况下,服务器将会收到对其存活探测的响应,但该响应是一个复位,从而引起服务器对连接的终止。
4) 客户端主机活跃运行,但从服务器不可到达。这与状态2类似,因为TCP无法区别它们两个。它所能表明的仅是未收到对其探测的回复。
服务器不必担心客户端主机被关闭然后重启的情况(这里指的是操作员执行的正常关闭,而不是主机的崩溃)。当系统被操作员关闭时,所有的应用程序进程(也就是客户端进程)都将被终止,客户端TCP会在连接上发送一个FIN。收到这个FIN后,服务器TCP向服务器进程报告一个文件结束,以允许服务器检测这种状态。
在第一种状态下,服务器应用程序不知道存活探测是否发生。凡事都是由TCP层处理的,存活探测对应用程序透明,直到后面2,3,4三种状态发生。在这三种状态下,通过服务器的TCP,返回给服务器应用程序错误信息。(通常服务器向网络发出一个读请求,等待客户端的数据。如果存活特征返回一个错误信息,则将该信息作为读操作的返回值返回给服务器。)在状态2,错误信息类似于“连接超时”。状态3则为“连接被对方复位”。第四种状态看起来像连接超时,或者根据是否收到与该连接相关的ICMP错误信息,而可能返回其它的错误信息。

三、在Linux中如何使用keepalive?[2]
Linux has built-in support for keepalive. You need to enable TCP/IP networking in order to use it. You also need procfs support andsysctl support to be able to configure the kernel parameters at runtime.
The procedures involving keepalive use three user-driven variables:

tcp_keepalive_time
    the interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe; after the connection is marked to need keepalive, this counter is not used any further
tcp_keepalive_intvl
    the interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
tcp_keepalive_probes
    the number of unacknowledged probes to send before considering the connection dead and notifying the application layer

Remember that keepalive support, even if configured in the kernel, is not the default behavior in Linux. Programs must request keepalive control for their sockets using the setsockopt interface. There are relatively few programs implementing keepalive, but you can easily add keepalive support for most of them following the instructions.
上面一段话已经说得很明白,linux内核包含对keepalive的支持。其中使用了三个参数:tcp_keepalive_time(开启keepalive的闲置时长)tcp_keepalive_intvl(keepalive探测包的发送间隔) 和tcp_keepalive_probes (如果对方不予应答,探测包的发送次数);如何配置这三个参数呢?
There are two ways to configure keepalive parameters inside the kernel via userspace commands:

    procfs interface
    sysctl interface

We mainly discuss how this is accomplished on the procfs interface because it's the most used, recommended and the easiest to understand. The sysctl interface, particularly regarding the sysctl(2) syscall and not the sysctl(8) tool, is only here for the purpose of background knowledge.
The procfs interface
This interface requires both sysctl and procfs to be built into the kernel, and procfs mounted somewhere in the filesystem (usually on/proc, as in the examples below). You can read the values for the actual parameters by "catting" files in /proc/sys/net/ipv4/directory:

  # cat /proc/sys/net/ipv4/tcp_keepalive_time
  7200
  # cat /proc/sys/net/ipv4/tcp_keepalive_intvl
  75
  # cat /proc/sys/net/ipv4/tcp_keepalive_probes
  9

The first two parameters are expressed in seconds, and the last is the pure number. This means that the keepalive routines wait for two hours (7200 secs) before sending the first keepalive probe, and then resend it every 75 seconds. If no ACK response is received for nine consecutive times, the connection is marked as broken.
Modifying this value is straightforward: you need to write new values into the files. Suppose you decide to configure the host so that keepalive starts after ten minutes of channel inactivity, and then send probes in intervals of one minute. Because of the high instability of our network trunk and the low value of the interval, suppose you also want to increase the number of probes to 20.
Here's how we would change the settings:

  # echo 600 > /proc/sys/net/ipv4/tcp_keepalive_time
  # echo 60 > /proc/sys/net/ipv4/tcp_keepalive_intvl
  # echo 20 > /proc/sys/net/ipv4/tcp_keepalive_probes

To be sure that all succeeds, recheck the files and confirm these new values are showing in place of the old ones.
这样,上面的三个参数配置完毕。使这些参数重启时保持不变的方法请阅读参考文献[2]。

四、在程序中如何使用keepalive?[2]-[4]
All you need to enable keepalive for a specific socket is to set the specific socket option on the socket itself. The prototype of the function is as follows:

int setsockopt(int s, int level, int optname,
                 const void *optval, socklen_t optlen)

The first parameter is the socket, previously created with the socket(2); the second one must be SOL_SOCKET, and the third must beSO_KEEPALIVE . The fourth parameter must be a boolean integer value, indicating that we want to enable the option, while the last is the size of the value passed before.
According to the manpage, 0 is returned upon success, and -1 is returned on error (and errno is properly set).
There are also three other socket options you can set for keepalive when you write your application. They all use the SOL_TCP level instead of SOL_SOCKET, and they override system-wide variables only for the current socket. If you read without writing first, the current system-wide parameters will be returned.
TCP_KEEPCNT: overrides tcp_keepalive_probes
TCP_KEEPIDLE: overrides tcp_keepalive_time
TCP_KEEPINTVL: overrides tcp_keepalive_intvlint keepAlive = 1; // 开启keepalive属性
我们看到keepalive是一个开关选项,可以通过函数来使能。具体地说,可以使用以下代码:
setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
上面英文资料中提到的第二个参数可以取为SOL_TCP,以设置keepalive的三个参数(具体代码参考文献[3]),在程序中实现需要头文件“netinet/tcp.h”。当然,在实际编程时也可以采用系统调用的方式配置的keepalive参数。
关于setsockopt的其他参数可以参考文献[4]。

五、如何判断TCP连接是否断开?[3]
当tcp检测到对端socket不再可用时(不能发出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上errno为ETIMEDOUT。

来自:http://machael.blog.51cto.com/829462/211989/
分页: 30/40 第一页 上页 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 下页 最后页 [ 显示模式: 摘要 | 列表 ]