志达IT
做快乐程序员

sigpipe信号屏蔽不了(怎么防止信号屏蔽器)

sigpipe信号屏蔽不了

服务器close一个衔接时,若client端接着发数据。依据TCP协议的规定,会收到一个RST呼应,client再往这个服务器发送数据时,体系会宣布一个SIGPIPE信号给进程,告诉进程这个衔接现已断开了,不要再写了。
又或许当一个进程向某个现已收到RST的socket履行写操作是,内核向该进程发送一个SIGPIPE信号。该信号的缺省学位是停止进程,因而进程必须捕获它避免不甘愿的被停止。
依据信号的默许处理规矩SIGPIPE信号的默许履行动作是terminate(停止、退出),所以client会退出。若不想客户端退出能够把SIGPIPE设为SIG_IGN
如:signal(SIGPIPE,SIG_IGN);
这时SIGPIPE交给了体系处理。
服务器采用了fork的话,要收集废物进程,避免僵尸进程的发生,能够这样处理:
signal(SIGCHLD,SIG_IGN);
交给体系init去收回。
这里子进程就不会发生僵尸进程了。
在linux下写socket的程序的时候,假如尝试send到一个disconnectedsocket上,就会让底层抛出一个SIGPIPE信号。
这个信号的缺省处理方法是退出进程,大多数时候这都不是咱们希望的。因而咱们需要重载这个信号的处理方法。调用以下代码,即可安全的屏蔽SIGPIPE:sigpipe
structsigactionsa;
sa.sa_handler=SIG_IGN;
sigaction(SIGPIPE,&sa,0);
signal设置的信号句柄只能起一次作用,信号被捕获一次后,信号句柄就会被还原成默许值了。
sigaction设置的信号句柄,能够一直有用,值到你再次改动它的设置。
structsigactionaction;
action.sa_handler=handle_pipe;
sigemptyset(&action.sa_mask);
action.sa_flags=0;
sigaction(SIGPIPE,&action,NULL);
voidhandle_pipe(intsig)
{
//不做任何处理即可
}
RST的意义为“复位”,它是TCP在某些过错状况下所宣布的一种TCP分节。有三个条件能够发生RST:
1),SYN到达某端口但此端口上没有正在监听的服务器。
2),TCP想撤销一个已有衔接
3),TCP接纳了一个根本不存在的衔接上的分节。
1.Connect函数回来过错ECONNREFUSED:
假如对客户的SYN的呼应是RST,则标明该服务器主机在咱们指定的端口上没有进程在等候与之衔接(例如服务器进程也许没有发动),这称为硬错(harderror),客户一接纳到RST,马上就回来过错ECONNREFUSED.
TCP为监听套接口维护两个行列。两个行列之和不超越listen函数第二个参数backlog。
当一个客户SYN到达时,若两个行列都是满的,TCP就忽略此分节,且不发送RST.这个因为:这种状况是暂时的,客户TCP将重发SYN,希望不久就能在行列中找到空闲条目。要是TCP服务器发送了一个RST,客户connect函数将立即发送一个过错,强制使用进程处理这种状况,而不是让TCP正常的重传机制来处理。还有,客户差异不了这两种状况:作为SYN的呼应,意为“此端口上没有服务器”的RST和意为“有服务器在此端口上但其行列满”的RST.
Posix.1g答应以下两种处理方法:忽略新的SYN,或为此SYN呼应一个RST.历史上,一切源自Berkeley的实现都是忽略新的SYN。
2.假如杀掉服务器端处理客户端的子进程,进程退出后,关闭它翻开的一切文件描述符,此刻,当服务器TCP接纳到来自此客户端的数据时,由于先前翻开的那个套接字接口的进程已停止,所以以RST呼应。
常常遇到的问题:
假如不判别read,write函数的回来值,就不知道服务器是否呼应了RST,此刻客户端假如向接纳了RST的套接口进行写操作时,内核给该进程发一个SIGPIPE信号。此信号的缺省行为便是停止进程,所以,进程必须捕获它避免不甘愿地被停止。
进程不论是捕获了该信号并从其信号处理程序回来,还是不理睬该信号,写操作都回来EPIPE过错。
3.服务器主机溃散后重启
假如服务器主机与客户端建立衔接后溃散,假如此刻,客户端向服务器发送数据,而服务器现已溃散不能呼应客户端ACK,客户TCP将持续重传数据分节,企图从服务器上接纳一个ACK,假如服务器一直溃散客户端会发现服务器现已溃散或目的地不可达,但或许需要比较长的时间;假如服务器在客户端发现溃散前重启,服务器的TCP丢失了溃散前的一切衔接信息,所以服务器TCP对接纳的客户数据分节以RST呼应。
二、关于socket的recv:
关于TCPnon-blockingsocket,recv回来值==-1,但是errno==EAGAIN,此刻表明在履行recv时相应的socketbuffer中没有数据,应该持续recv。
【IfnomessagesareavailableatthesocketandO_NONBLOCKisnotsetonthesocket’sfiledescriptor,recv()shallblockuntilamessagearrives.IfnomessagesareavailableatthesocketandO_NONBLOCKissetonthesocket’sfiledescriptor,recv()shallfailandseterrnoto[EAGAIN]or[EWOULDBLOCK].】
关于UDPrecv应该一直读取直到recv()==-1&&errno==EAGAIN,表明buffer中数据包被悉数读取。
接纳数据时常遇到Resourcetemporarilyunavailable的提示,errno代码为11(EAGAIN)。这标明你在非堵塞形式下调用了堵塞操作,在该操作没有完成就回来这个过错,这个过错不会破坏socket的同步,不用管它,下次循环接着recv就能够。对非堵塞socket而言,EAGAIN不是一种过错。在VxWorks和Windows上,EAGAIN的名字叫做EWOULDBLOCK。其实这算不上过错,只是一种异常而已。sigpipe

怎么防止信号屏蔽器

屏蔽器它并不是真正的起到屏蔽的作用,从原理上讲,它主要是起到了搅扰的作用,就像电影中的电磁搅扰相同。手机信号屏蔽器作业中以一定的速度从信道的低端频率向高端扫描,该扫描能够在手机接纳报文信号中构成乱码搅扰,导致手机不能检测出从基站发出的正常数据,使手机不能与基站树立联接,然后手机就会表现为查找网络、无信号、无服务体系等现象。已然知道了原理,那么想要防止手机被屏蔽就有几种做法:1.对屏蔽器进行搅扰先弄到屏蔽器内部电路的作业频率,然后用相同的频率辐射源放置在屏蔽器邻近,施以叫大功率的电平,这样屏蔽器就不能正常作业。但这个难度有点高,而且有点傻。2.制造一个屏蔽体,将屏蔽器放置在屏蔽体中,这样就能够使屏蔽器完全失效。但这样的做法仍是有点傻,你都知道屏蔽器放在那里了,直接切断电源不就能够了!3.经过手机进行手调点开手机设置,点开“网络设置”中的“网络查找”,把网络形式改为“手动形式”,然后进入“网络查找”,等到出现“中国移动”或“中国联通”的字样,就当即退出,这时手机就会有信号了,但是反屏蔽时间的长短要看手机的质量,一般也就几秒到十几秒左右,但是这个办法能够一直使用。总结一下,办法1和2,在实践中难以做到,毕竟不知道屏蔽器放在那里,就算真的找到了。还费什么话,直接切断电源不就行了,办法3也就成了仅有的解决方案,但是这个对手机质量要求有点高。

赞(0)
未经允许不得转载:志达IT网站 » sigpipe信号屏蔽不了(怎么防止信号屏蔽器)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

志达IT网站 每天分享编程和互联网的IT技术博客

登录/注册联系我们