来自初学C程序员的Hello。
我有一个简单的服务器客户端设置。我只希望一个客户端连接到服务器,但我希望其他客户端能够尝试获取服务器被占用的消息。
我能够通过一个客户端连接到服务器,并让其他尝试连接的客户知道没有空间。当客户端告诉服务器关闭时,我的问题出现了。子进程能够突破循环并终止。但是,父级无法使用管道从子级接收消息,因为它卡在accept
上。
我可以使用kill(2)
来结束父级,但是我会在关闭套接字和文件时获得干净的终止吗?
我还尝试让父母不要停止使用fcntl(sock_desc, F_SETFL, fcntl(sock_desc, F_GETFL, 0) | O_NONBLOCK);
,但这会带来新的问题。
我想以某种方式让孩子告诉父母跳过accept
行并继续,以便它获取管道消息并退出循环。
如果这是终止服务器的坏方法,我将不胜感激。
简化的服务器代码:
void termination_handler (int signum)
{
if(signum == SIGTERM){
//Is this where the accept call is changed?
}
}
void main(){
struct sigaction sa = {0}; //2b) Initialise the struct sigaction variable to all 0s beforehand.
sa.handler = termination_handler; //2a) Set the member for handler (to the signal-handler function)
sigaction(SIGTERM, &sa, NULL);
pid_t pid;
int loop = 1;
while(loop){
int sock = accept(net_sock, NULL, NULL); //After connection
//parent is stuck here
if(kill(pid,0) == -1){
pid = fork();
}
else{
//Tell second client there is no room and close socket
}
//Child
if(pid == 0){
while(loop){
//Read signal in from client to end child loop and terminate child
//Write with pipe to parent to end parent loop and terminate parent
kill(getppid(), SIGTERM) // Is this how I do it?
}
}
//Parent
else{
close(sock);
//Read with pipe from child to end loop
//After first connection, the parent won't get this message
}
}
答案 0 :(得分:2)
操作系统将为您关闭文件描述符。除非您有其他清理工作要做(例如写入文件或删除某些文件),否则使用未处理的终止信号(例如SIGTERM
或SIGINT
)进行杀死就足够了。
如果你还有其他清理工作要做,请让孩子用父母信号处理器建立信号处理父母的信号(你需要用sigaction
建立处理程序)。这将使accept
与返回码-1
和errno == EINTR
中断,让您可以做任何您需要做的事情。
volatile sig_atomic_t usr1 = 0;
void usr1_handler(int Sig) { usr1 = 1; }
//...
int main() { //...
sigaction(SIGUSR1, &(struct sigaction){.sa_handler=usr1_handler},0);
//...
usr1 = 0;
sock = accept( /*... */ );
if ( -1 == sock && EINTR == errno && usr1 ) //was interrupted by USR1
/* cleanup and exit */;
答案 1 :(得分:1)
让孩子在结束前给孩子发信号。如果正确完成,accept()
将返回信号接收,返回-1
并将errno
设置为EINTR
。
返回值
成功完成后, accept()将返回已接受套接字的非负文件描述符。否则,应返回-1,设置errno以指示错误,[...]
[...]
<强> 错误 强>
如果出现以下情况,accept()函数将失败:
[...]
[EINTR] accept()函数被有效连接到达之前捕获的信号中断。