C语言标准输入被关闭程序死循环

#现象

如果测试端使用标准输入流的标识进行循环控制while(任意字符==q){scanf("%c\n",&q);}形式程序

此端发送,循环内嵌入UDP发送,嵌入的无其他形势跳出循环。

彼端接收,可查看此端发送条数。

 

1.在CRT开始运行./a.out args,并键盘输入控制,程序还在循环中,直接X掉CRT程序可能变成后台程序继续运行,略过scanf,保持原来的值死循环,暂时定为【标准输入控制失控】。在其他的crt窗口中ps -ef|grep a.out。有可能出现该程序还在后端运行。根据增加while(任意==q&&i<5){scanf("%c\n",&q);}可以显示发现输入失控的时候,程序循环依旧进行。程序会接收到signo=1.程序退出。一旦忽略该信号SIGHUP。程序会后台一直运行,即死循环。【在该信号默认程序退出的情况下,程序输入失控一段时间】

freopen("input.log","a+",stdout);while(任意==q&&i<5){scanf("%c\n",&q);printf(":%d:\n",q);}可以通过日志查看crt失控的过程依旧是原来的q值。

 

2.使用nohup ./a.out args 启用程序,也出现【标准输入控制失控】。在行首同时ctrl和c按键中断程序退出。一旦忽略,依旧失控。

 

3.使用nohup ./a.out args & 启用程序【标准输入控制失控】。kill -9 `pidof a.out`程序强制退出

 

#猜测原因

根据守护进程,代码来自

https://www.cnblogs.com/wiessharling/p/4105956.html

猜测 标准输入流 关闭

bool daemonize()
{
    pid_t pid = fork();
    if ( pid < 0 )
    {
        return false;
    }
    else if ( pid > 0 )
    {
        exit( 0 );
    }

    umask( 0 );

    pid_t sid = setsid();
    if ( sid < 0 )
    {
        return false;
    }

    if ( ( chdir( "/" ) ) < 0 )
    {
        /* Log the failure */
        return false;
    }
    close( STDIN_FILENO );
    close( STDOUT_FILENO );
    close( STDERR_FILENO );

    open( "/dev/null", O_RDONLY );
    open( "/dev/null", O_RDWR );
    open( "/dev/null", O_RDWR );
    return true;
}

#模拟程序

 

#include<stdio.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<errno.h>
#include<unistd.h>
int main()
{
int a_errno=0;
int ret=0;
char q='c';
printf("<%d>\n",q);

close( STDIN_FILENO );
ret=scanf("%c\n",&q);
if(EOF==ret)
{ 
        a_errno=errno;
}
  printf("[%d] ret=%d eno[%d]%s\n",q,ret,a_errno,strerror(a_errno));

return 0;
}

可发现打印的两次都为99

#解决方法

c=getchar();命令行后所有字符均被读入

标准输入的参数前面进行赋值和判断的不一致的参数。

如果是int如果使用清空,一旦是0,也会同样失效。

程序kill掉命令a.out 为程序名
kill -9 `pidof a.out`
/*彼端*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#define LOGP  printf

void  udp_server_test(int lsa_port)
{
  	int 				socketfd=0;
	int				iReadLen=-1;
	int				peer_len=0;
	char				readbuf[1500]; 
	union sockaddr_types {
         struct sockaddr_storage storage;
         struct sockaddr addr; 
        struct sockaddr_in in4;
        struct sockaddr_in6 in6;
        };
	union sockaddr_types    peer;
	union sockaddr_types	local_server;
	char			IP_peer[INET6_ADDRSTRLEN];
	unsigned  int           port_peer;  
	int                      eno;

	bzero(&local_server, sizeof(local_server)); 
	
#if    1
	  local_server.in4.sin_family = AF_INET;
          local_server.in4.sin_addr.s_addr = htonl(INADDR_ANY);
          local_server.in4.sin_port = htons(lsa_port);

#else
 
	   local_server.in6.sin6_family = AF_INET6;
           local_server.in6.sin6_addr = in6addr_any;
           local_server.in6.sin6_port = htons(lsa_port);
#endif 
        /* AF_INET:IPv4;  AF_INET6:Allow IPv4 or IPv6 */
	socketfd = socket(local_server.addr.sa_family, SOCK_DGRAM, 0);
	if(socketfd < 0)
	{
	        eno=errno;
		LOGP("socket failed!errno[%d][%s].",eno,strerror(eno));
	}
	else
	{
		LOGP("socket suc.\n");
	}

	if (bind(socketfd, &local_server.addr, sizeof(local_server)) < 0)
	{
	        eno=errno;
		LOGP("bind socket failed!errno[%d][%s].",eno,strerror(eno));
	}
	else
	{
		LOGP("bind suc.\n");
	}

	//freopen("out_ser.log","a+",stdout);
	while(1)
	{
		memset(readbuf,0,sizeof(readbuf));
         peer_len = sizeof(struct sockaddr_storage);	
		iReadLen = recvfrom(socketfd, readbuf, sizeof(readbuf), 0, &peer.addr, (socklen_t*)&peer_len);
		if(0==iReadLen)
		{
		   continue;
		}
		if(iReadLen<0)
		{    eno=errno;
		    if(EBADF==eno)
			break;/*The socket argument is not a valid file descriptor*/
		     else continue;
		} 
		  { 
		       if(NULL==inet_ntop(peer.addr.sa_family, 
		         (AF_INET==peer.addr.sa_family? 
			 ((void*)&peer.in4.sin_addr):((void*)&peer.in6.sin6_addr)),
		           IP_peer, sizeof(IP_peer)))
		       {
		       } 
		       port_peer=ntohs(AF_INET==peer.addr.sa_family?peer.in4.sin_port:peer.in6.sin6_port);
                   
          } 
		printf("IP[%s:%d]len=%d content=[%s]\n",IP_peer,port_peer,iReadLen,readbuf); 

	} 
	close(socketfd); 

}

int main(int argc,char *argv[])
{ 
	if(argc!=2)
   {
    printf("./Usage {port}\n");
   return 1;
   }
   udp_server_test(atoi(argv[1]));
   return 0;	
}
/*旧的此*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<signal.h>
int gsigno;
#define exit_printf(en,f,...)  do{fflush(stdout);freopen("fcexit.log","a+",stdout);printf(f,##__VA_ARGS__);fflush(stdout);exit(en);}while(0)
void Signcallback(int signo, siginfo_t *info, void *context){

    	
 gsigno=signo; 
  exit(1);	 
}
void registersignal()
{   
	  struct sigaction  ignoreact;
	  ignoreact.sa_handler = SIG_IGN;
           
	  ignoreact.sa_flags = SA_RESETHAND; 
	  sigaction(SIGHUP, &ignoreact, NULL); 
	   
	  struct sigaction  actp;
	  actp.sa_sigaction=Signcallback;
	  actp.sa_flags=SA_SIGINFO|SA_RESTART;
	  sigemptyset(&(actp.sa_mask));
	  sigaction(SIGTERM,&actp,NULL); 
	  sigaction(SIGQUIT,&actp,NULL); 
      sigaction(SIGPIPE, &actp, NULL);
      sigaction(SIGALRM, &actp, NULL); 
      sigaction(SIGILL, &actp, NULL);
      sigaction(SIGABRT, &actp,NULL);
      sigaction(SIGFPE, &actp, NULL);
      sigaction(SIGINT,&actp,NULL);
 
 	return ;

} 
 

void  exitHandle()
{
    time_t timer = time(NULL); 
    printf("ctime is %s", ctime(&timer)); 
    printf("<%d>test program exit\n",gsigno);  
}

int main(int argc,char *argv[])
{

atexit(exitHandle);/*注册终止函数*/
registersignal();  

 if(argc!=3)
{
printf("./Usage [ip] [port]\n");
return 1;
}
int sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
 {
perror("socket");
return 2;

}

 struct sockaddr_in rsa;
 rsa.sin_family=AF_INET;
 rsa.sin_port=htons(atoi(argv[2]));
 rsa.sin_addr.s_addr=inet_addr(argv[1]);

 char buf[1024];
        int buflen =0;
 struct sockaddr_in peer;
 char quitf='c';
int i=0;
int ret=0;
freopen("input.log","a+",stdout);
while('c'==quitf)
{  
  i++; 
  buflen=sprintf(buf,"%d",i);
  sendto(sock,buf,buflen,0, (struct sockaddr*)&rsa,sizeof(rsa));
  ret=scanf("%c",&quitf);
  getchar();
  printf(":ret(%d)%d:\n",ret,quitf); 
 }
close(sock);
exit_printf(0,"\'%d\'",quitf);
return 0;
} 
/* 增加 quitf=-'c';*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<signal.h>
int gsigno;
#define exit_printf(en,f,...)  do{fflush(stdout);freopen("fcexit.log","a+",stdout);printf(f,##__VA_ARGS__);fflush(stdout);exit(en);}while(0)
void Signcallback(int signo, siginfo_t *info, void *context){

    	
 gsigno=signo; 
  exit(1);	 
}
void registersignal()
{   
	  struct sigaction  ignoreact;
	  ignoreact.sa_handler = SIG_IGN;
           
	  ignoreact.sa_flags = SA_RESETHAND; 
	  sigaction(SIGHUP, &ignoreact, NULL); 
	   
	  struct sigaction  actp;
	  actp.sa_sigaction=Signcallback;
	  actp.sa_flags=SA_SIGINFO|SA_RESTART;
	  sigemptyset(&(actp.sa_mask));
	  sigaction(SIGTERM,&actp,NULL); 
	  sigaction(SIGQUIT,&actp,NULL); 
      sigaction(SIGPIPE, &actp, NULL);
      sigaction(SIGALRM, &actp, NULL); 
      sigaction(SIGILL, &actp, NULL);
      sigaction(SIGABRT, &actp,NULL);
      sigaction(SIGFPE, &actp, NULL);
      sigaction(SIGINT,&actp,NULL);
 
 	return ;

} 
 

void  exitHandle()
{
    time_t timer = time(NULL); 
    printf("ctime is %s", ctime(&timer)); 
    printf("<%d>test program exit\n",gsigno);  
}

int main(int argc,char *argv[])
{

atexit(exitHandle);/*注册终止函数*/
registersignal();  

 if(argc!=3)
{
printf("./Usage [ip] [port]\n");
return 1;
}
int sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
 {
perror("socket");
return 2;

}

 struct sockaddr_in rsa;
 rsa.sin_family=AF_INET;
 rsa.sin_port=htons(atoi(argv[2]));
 rsa.sin_addr.s_addr=inet_addr(argv[1]);

 char buf[1024];
        int buflen =0;
 struct sockaddr_in peer;
 char quitf='c';
int i=0;
int ret=0;
freopen("input.log","a+",stdout);
while('c'==quitf)
{  
  i++; 
  buflen=sprintf(buf,"%d",i);
  sendto(sock,buf,buflen,0, (struct sockaddr*)&rsa,sizeof(rsa));
  quitf=-'c';
  ret=scanf("%c",&quitf);
  getchar();
  printf(":ret(%d)%d:\n",ret,quitf); 
 }
close(sock);
exit_printf(0,"\'%d\'",quitf);
return 0;
} 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用8255驱动数码管和矩阵键盘的C语言程序: ``` #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <dos.h> #define PORT_A 0x0280 // 8255的端口A地址 #define PORT_B 0x0281 // 8255的端口B地址 #define PORT_C 0x0282 // 8255的端口C地址 void delay(int milliseconds) // 延时函数 { long wait; clock_t now, start; wait = milliseconds * (CLK_TCK / 1000); start = clock(); do { now = clock(); } while ((now - start) < wait); } void writeData(unsigned char data) // 向8255的端口C写入数据 { outp(PORT_C, data); } void writeControl(unsigned char control) // 向8255的端口B写入控制字 { outp(PORT_B, control); } void setDisplay(unsigned char data) // 显示一个数字 { writeData(data); // 先写入数据 writeControl(0x01); // 写入控制字,选择数码管 delay(1); // 延时一段时间 writeControl(0x00); // 关闭数码管 } int main() { unsigned char keymap[4][4] = { // 键盘映射表 { '1', '2', '3', 'A' }, { '4', '5', '6', 'B' }, { '7', '8', '9', 'C' }, { '*', '0', '#', 'D' } }; unsigned char displaymap[10] = { // 数码管映射表 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F // 9 }; unsigned char key, data; int i, j; writeControl(0x80); // 写入控制字,初始化8255 writeData(0x00); // 初始化端口C writeControl(0x82); // 选择端口B,设为输入模式 delay(1); // 延时一段时间 while (1) { for (i = 0; i < 4; i++) { // 扫描键盘 writeControl(0x82); // 选择端口B,设为输入模式 data = inp(PORT_B) & 0x0F; if (data != 0x0F) { delay(10); // 延时一段时间,消抖 data = inp(PORT_B) & 0x0F; if (data != 0x0F) { key = keymap[i][data]; setDisplay(displaymap[data]); // 显示按下的数字 while (inp(PORT_B) != 0x0F); // 等待键盘释放 printf("%c", key); // 输出按下的键 } } writeControl(0x81); // 选择端口A,设为输出模式 writeData(0xFF); // 关闭数码管 for (j = 0; j < 4; j++) { // 显示数码管 writeData(displaymap[j]); writeControl(0x01); delay(1); writeControl(0x00); } } } return 0; } ``` 这个程序使用8255芯片来控制数码管和矩阵键盘。首先定义了8255的三个端口地址,以及延时函数。然后定义了向端口C和B写入数据的函数,以及显示一个数字的函数。接着定义了键盘映射表和数码管映射表。在主函数中,先初始化8255,然后进入一个死循环,不断扫描键盘和显示数码管。扫描键盘时,循环扫描4行4列的矩阵键盘,如果有键被按下,则根据映射表得到按下的键。然后显示按下的数字,并输出按下的键。显示数码管时,循环显示四个数字。最后,程序无限循环,等待下一次按键。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值