RS-232c의 예제프로그램에 관한 질문입니다
글쓴이: iamsjkim / 작성시간: 화, 2003/10/14 - 6:30오후
host A에서는 비동기 입력예제(canonical async)를 돌리고 있고
host B에서는 non-canonical 입력예제를 조금 수정해서 돌리고 있는데요.
비동기 입력예제의 경우 read()문 다음에 write()문을 넣어서 메세지를 전송하도록 살짝 고치고
non-canonical의 경우에는 write()문을 삽입하고 read()문으로 메세지를 받도록 고쳐서 컴파일후 실행시켰습니다.
그런데 host A를 실행시키면 B의 입력문은 받아보는데 A가 보내는 메세지는 B가 받아보질 못하네요. (받은 메세지를 출력하도록 코딩했는데 read()문은 에러없이 통과되면서 출력문은 없습니다(read()의 리턴값이 0입니다-_-))
왜 메세지를 받지못하는지.. 아시는 고수님들 답변 부탁드립니다.
(두 host간에 통신할때 둘다 canonical이나 non-canonical로 일치시켜야하는지요? 이것과는 상관없나요?)
또.. 이상한게 있습니다..
A에서 write()안할적에는 B의 메세지를 받아보다가 A에 write()코드를 넣으면 B의 메세지를 받지도 못합니다. 그런데 B의 컴퓨터를 껐다가 켜면 A의 코드에 Write()가 있어도 B의 메세지는 받아보지만 B가 A의 메세지는 여전히 받아보지 못하네요..
참고로..
host A 코드 :
#include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <sys/types.h> #define MODEMDEVICE "/dev/ttyS0" #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; void signal_handler_IO (int status); /* signal handler 함수 정의 */ int wait_flag=TRUE; /* signal을 받지 않은 동안은 TRUE */ main() { int fd,c, res, i; struct termios oldtio,newtio; struct sigaction saio; /* signal action의 정의 */ char buf[255],send[255]; /* Non-blocking 모드로 시리얼 장치를 연다(read 함수 호출 후 즉각 리턴) */ fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd <0) {perror(MODEMDEVICE); exit(-1); } /* install the signal handler before making the device asynchronous */ /* 장치를 비동기 모드로 만들기 전에 signal handler */ saio.sa_handler = signal_handler_IO; /* sigemptyset(&block_mask); sigaddset(&block_mask,SIGIO); saio.sa_mask = block_mask; */ sigemptyset(&saio.sa_mask); //// // sigdelset(&saio.sa_mask,TERM); saio.sa_flags = 0; saio.sa_restorer = NULL; sigaction(SIGIO,&saio,NULL); /* SIGIO signal을 받을 수 있도록 한다. */ fcntl(fd, F_SETOWN, getpid()); /* file descriptor를 비동기로 만든다. (manual page를 보면 O_APPEND 와 O_NONBLOCK만이 F_SETFL에 사용할 수 있다고 되어 있다.) SIGIO 신호는 fd상에서 입력이나 출력이 가능하게 될때마다 보내어진다. 이 신호를 받을 프로세스나 프로세스 그룹은 fcntl함수에 F_SETOWN명령을 사용해서 선택할 수 있다 */ fcntl(fd, F_SETFL, FASYNC); tcgetattr(fd,&oldtio); /* save current port settings */ /* canonical 입력처리를 위한 포트 세팅 */ bzero(&newtio,sizeof(newtio)); newtio.c_cflag = (CRTSCTS | CS8 | CLOCAL | CREAD); cfsetispeed(&newtio,B9600); cfsetospeed(&newtio,B9600); /* newtio.c_cflag = ~CSIZE; newtio.c_cflag = ~PARENB; newtio.c_cflag = ~CSTOPB; */ newtio.c_iflag = (IGNPAR | ICRNL); newtio.c_oflag = 0; newtio.c_lflag = ICANON; newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /* loop while waiting for input. normally we would do something useful here */ while (STOP==FALSE) { printf(".\n");usleep(100000); /* after receiving SIGIO, wait_flag = FALSE, input is available and can be read */ if (wait_flag==FALSE) { res = read(fd,buf,255); buf[res]=0; printf(":%s:%d\n", buf, res); for(i=0;i<res;i++) send[i] = buf[i]; sleep(1); i = write(fd,send,res); printf("write ok....%d\n",i); if (res==1) STOP=TRUE; /* stop loop if only a CR was input */ wait_flag = TRUE; /* wait for new input */ } } /* restore old port settings */ tcsetattr(fd,TCSANOW,&oldtio); } /*************************************************************************** * signal handler. sets wait_flag to FALSE, to indicate above loop that * * characters have been received. * ***************************************************************************/ void signal_handler_IO (int status) { printf("received SIGIO signal.\n"); wait_flag = FALSE; }
host B 코드 :
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #define BAUDRATE B38400 #define MODEMDEVICE "/dev/ttyS0" #define _POSIX_SOURCE 1 /* POSIX compliant source */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; main() { int fd,c, res,i; struct termios oldtio,newtio; char buf[255]; fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY ); if (fd <0) {perror(MODEMDEVICE); exit(-1); } tcgetattr(fd,&oldtio); /* 현재 설정을 oldtio에 저장 */ bzero(&newtio, sizeof(newtio)); cfsetispeed(&newtio,B9600); cfsetospeed(&newtio,B9600); newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD; newtio.c_iflag = IGNPAR; newtio.c_oflag = 0; /* set input mode (non-canonical, no echo,...) */ newtio.c_lflag = 0; // newtio.c_cc[VTIME] = 0; /* 문자 사이의 timer를 disable */ // newtio.c_cc[VMIN] = 5; /* 최소 5 문자 받을 때까진 blocking */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); // while (STOP==FALSE) { /* loop for input */ printf("after while....\n"); res = write(fd,"this is the test\n",17); buf[res]=0; /* '\0' 종료 문자열(printf를 하기 위해) */ res = read(fd,buf,255); printf(":%s", buf);printf("\n"); if (buf[0]=='z') STOP=TRUE; // } tcsetattr(fd,TCSANOW,&oldtio); }
Forums:
댓글 달기