C 作为后台进程运行时,我的服务器不接受连接
我用C写了一个简单的服务器,它回答8888端口的连接。它工作得很好…直到我尝试将其作为后台进程运行 当我像这样运行它时C 作为后台进程运行时,我的服务器不接受连接,c,sockets,tcp,client,C,Sockets,Tcp,Client,我用C写了一个简单的服务器,它回答8888端口的连接。它工作得很好…直到我尝试将其作为后台进程运行 当我像这样运行它时 $ ./server 然后尝试与客户机连接,工作正常。当我尝试像这样运行它时: $ ./server & 或者如果我像这样运行它 $ ./server 然后用CTRL+z将其分离,并尝试与我获得的客户端连接 Connection Refused 以前有人遇到过这个问题吗?如果能找到解决办法,我将不胜感激 以下是根据请求接受调用的代码: char remot
$ ./server
然后尝试与客户机连接,工作正常。当我尝试像这样运行它时:
$ ./server &
或者如果我像这样运行它
$ ./server
然后用CTRL+z将其分离,并尝试与我获得的客户端连接
Connection Refused
以前有人遇到过这个问题吗?如果能找到解决办法,我将不胜感激
以下是根据请求接受调用的代码:
char remoteIP[ INET6_ADDRSTRLEN ];
int yes=1; /* for setsockopt() SO_REUSEADDR, below */
int i, rv;
struct addrinfo hints, *ai, *p;
FD_ZERO( &master ); /* clear the master and temp sets */
FD_ZERO( &read_fds );
/* get us a socket and bind it */
memset( &hints, 0, sizeof hints );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ( ( rv = getaddrinfo( NULL, URL_PORT, &hints, &ai ) ) != 0 )
{
/* fprintf( stderr, "selectserver: %s\n", gai_strerror( rv ) ); */
exit( 1 );
}
/* printf( "Listening on port %s for URLs...\n", URL_PORT ); */
for( p = ai; p != NULL; p = p->ai_next )
{
listener = socket( p->ai_family, p->ai_socktype, p->ai_protocol );
if ( listener < 0 )
{
continue;
}
/* lose the pesky "address already in use" error message */
setsockopt( listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof( int ) );
if ( bind( listener, p->ai_addr, p->ai_addrlen) < 0 )
{
close( listener );
continue;
}
break;
}
/* if we got here, it means we didn't get bound */
if ( p == NULL )
{
/* fprintf( stderr, "selectserver: failed to bind\n" ); */
exit( 2 );
}
freeaddrinfo( ai ); /* all done with this */
/* listen */
if ( listen( listener, 10 ) == -1 )
{
perror( "listen" );
exit( 3 );
}
/* add the listener to the master set */
FD_SET( listener, &master );
/* keep track of the biggest file descriptor */
fdmax = listener; /* so far, it's this one */
/* main loop */
for( ; ; ) {
for( i = 0; i <= fdmax; i++ )
{
if ( SOCKETS[ i ].in_progress )
{
if ( pthread_join( SOCKETS[ i ].thread, NULL ) != 0 )
{
/* fprintf( stderr, "Error terminating thread %i\n", i ); */
}
else
{
SOCKETS[ i ].in_progress = FALSE;
}
}
}
read_fds = master; /* copy it */
if ( select( fdmax + 1, &read_fds, NULL, NULL, NULL ) == -1 )
{
perror( "select" );
exit(4);
}
/* run through the existing connections looking for data to read */
for( i = 0; i <= fdmax; i++ ) {
if ( FD_ISSET( i, &read_fds ) && SOCKETS[ i ].in_progress == FALSE )
{
/* we got one!! */
if ( i == listener )
{
/* handle new connections */
addrlen = sizeof remoteaddr;
newfd = accept( listener, ( struct sockaddr * ) &remoteaddr, &addrlen );
if ( newfd == -1 )
{
perror( "accept" );
}
else
{
FD_SET( newfd, &master ); /* add to master set */
if ( newfd > fdmax )
{ /* keep track of the max */
fdmax = newfd;
}
/*
printf(
"selectserver: new connection from %s on socket %d\n",
inet_ntop( remoteaddr.ss_family, get_in_addr( ( struct sockaddr* ) &remoteaddr ), remoteIP, INET6_ADDRSTRLEN ), newfd );
*/
}
}
您的进程从其控制终端读取或写入数据,因此当您在后台使用&运行它时,它会被SIGTTIN或sigttoo停止 有关摘录自: 只允许前台进程读取或写入 航空站尝试从写入到读取的后台进程 终端发送一个SIGTTIN SIGTOU信号 驱动程序,除非被捕获,否则将暂停进程 SIGTTOU的发送由一个默认为off的标志控制,因此您的问题可能是由从控制终端读取引起的。如果要防止后台进程写入终端,即重新启用向尝试后台写入的进程发送SIGTOU,请使用以下命令:
stty tostop
bg %1
您可以通过以下操作恢复到默认行为:
stty -tostop
当按下Ctrl+Z键时,会将SIGTSTP发送到进程。此信号的默认配置也是停止进程。如果要使进程继续在后台运行,请使用以下命令:
stty tostop
bg %1
请注意,在您的情况下,工作编号可能不同。使用job命令进行检查
请注意,与SIGSTOP不同,如果您不喜欢此行为,则这三个信号可以由您的进程处理或忽略。读/写系统调用随后将返回EINTR而不是阻塞。您的进程从其控制终端读取或写入,因此当您在后台使用&运行它时,它将被SIGTTIN或SIGTOU停止 有关摘录自: 只允许前台进程读取或写入 航空站尝试从写入到读取的后台进程 终端发送一个SIGTTIN SIGTOU信号 驱动程序,除非被捕获,否则将暂停进程 SIGTTOU的发送由一个默认为off的标志控制,因此您的问题可能是由从控制终端读取引起的。如果要防止后台进程写入终端,即重新启用向尝试后台写入的进程发送SIGTOU,请使用以下命令:
stty tostop
bg %1
您可以通过以下操作恢复到默认行为:
stty -tostop
当按下Ctrl+Z键时,会将SIGTSTP发送到进程。此信号的默认配置也是停止进程。如果要使进程继续在后台运行,请使用以下命令:
stty tostop
bg %1
请注意,在您的情况下,工作编号可能不同。使用job命令进行检查
请注意,与SIGSTOP不同,如果您不喜欢此行为,则这三个信号可以由您的进程处理或忽略。读/写系统调用随后将返回EINTR而不是阻塞。如果在服务器处于后台时运行ps,您是否看到它正在运行?是的,我可以看到它正在运行。您是否能够在执行接受调用的地方发布代码和某些上下文?已发布。您可能会从beej的指南中注意到一些相似之处。Ctrl+Z会在Linux上挂起该过程,因此这并不奇怪。然而,令人惊讶的是,./server&version无法工作。如果您取消对printfs的注释,您在终端中会看到什么输出?如果您在服务器处于后台时运行ps,您是否看到它正在运行?是的,我可以看到它正在运行。您是否能够发布代码和执行accept调用的某个上下文?已发布。您可能会从beej的指南中注意到一些相似之处。Ctrl+Z会在Linux上挂起该过程,因此这并不奇怪。然而,令人惊讶的是,./server&version无法工作。如果取消对printf的注释,您在终端中看到了什么输出?printf是写入终端的方法吗?getc怎么样?我想那些只是用了标准输入法和标准输出法。是吗?我取消了一个getc呼叫,解决了这个问题。你太棒了!printf是写入终端的方法吗?getc怎么样?我想那些只是用了标准输入法和标准输出法。是吗?我取消了一个getc呼叫,解决了这个问题。你太棒了!