시리얼로 파일 전송 프로그램 - 문제 ;;

lukep2s의 이미지

시리얼로 파일을 주고 받기위해서 일단 테스트 삼아 만들어본건데 문제가 많습니다.

깨진 문자가 들어가고
파일이 전부 다 전송되지 않고
원본 파일과 줄바꿈 위치가 다릅니다.

받는 쪽에서 일단 동작하고 보내는 쪽에서 파일을 오픈하여 전송하는 방식입니다.
한번 확인 해주셨으면 합니다.

받는 쪽 소스
 
========================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <termios.h>
 
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
 
#include <errno.h>
#include <time.h>
 
#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
 
#define FALSE 0
#define TRUE 1
#define CRTSCTS 020000000000
#define MAX 255
#define DATA_MAX 20
#define GET_DONE 0
 
////////////////////////
FILE *fp1;
FILE *fp2;
 
long buffsize = 0;
 
long rFilesize = 0;
 
char serial_buf[MAX];
int fd;
int res;
struct termios oldtio,newtio;
//////////////////////////////////////////////////////////////////
 
void serial_open()
{
 
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }
 
        tcgetattr(fd,&oldtio);
        bzero(&newtio, sizeof(newtio));
 
        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
 
        newtio.c_iflag = ICRNL;
 
        newtio.c_lflag = ICANON;
 
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
 
}
 
void serial_close()
{
        tcsetattr(fd,TCSANOW,&oldtio);
        close(fd);
}
 
int get_data ()
{
        fp2 = fopen("c","wb"); // 파일을 복사할때는 binary 모드로 여는 편이 좋아요
        rFilesize = 72;
        while(rFilesize > 0)  // 파일 크기만큼 반복
        {
                fread(serial_buf, buffsize, 1,fd);
                printf("1%s1",serial_buf);
                write(fp2,serial_buf, sizeof(serial_buf));
 
                rFilesize --;
                bzero(serial_buf,MAX);
        }
 
        return 0;
}
 
int main()
{
        serial_open();
        fp2 = fopen("c","wb");
        res =0;
 
while(        read(fd,serial_buf,DATA_MAX)) {
                printf("%s\n\n %d",serial_buf,res);
                fwrite(serial_buf,MAX-50,1,fp2);        
                bzero(serial_buf,MAX);
        }
 
        return 0;
}

===========================================

보내는 쪽 소스

========================================

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <termios.h>
 
#include <stddef.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
 
#include <errno.h>
#include <time.h>
 
#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1
 
#define FALSE 0
#define TRUE 1
#define CRTSCTS 020000000000
#define MAX 255
#define DATA_MAX 20
#define GET_DONE 0
 
////////////////////////
FILE *fp1;
FILE *fp2;
 
long buffsize = 0;
 
long lFilesize = 0;
 
char serial_buf[MAX];
int fd;
int res;
struct termios oldtio,newtio;
//////////////////////////////////////////////////////////////////
 
void serial_open()
{
 
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }
 
        tcgetattr(fd,&oldtio);
        bzero(&newtio, sizeof(newtio));
 
        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
 
        newtio.c_iflag =  ICRNL;
 
        newtio.c_lflag = ICANON;
 
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
 
}
 
void serial_close()
{
        tcsetattr(fd,TCSANOW,&oldtio);
        close(fd);
}
 
void send_data( )
{
 
        fp1 = fopen("a","rb");
        if( fp1 == NULL )
        {
                exit(0);
        }
 
        fseek(fp1, 0, 2);
        lFilesize = ftell(fp1);
        fseek(fp1, 0, 0);  
        res = 0;
 
        while(lFilesize > 0)
        {
                if(lFilesize > DATA_MAX)
                        buffsize = DATA_MAX;
                else
                        buffsize = lFilesize;
 
                fread(serial_buf, buffsize,1,fp1);
                printf ( "%s",serial_buf);
                write(fd,serial_buf,buffsize);
 
                lFilesize -= buffsize;
 
                bzero(serial_buf,MAX);
        }
 
        bzero(serial_buf,MAX);
        fclose(fp1);
}
 
 
int main()
{
        serial_open();
        send_data();
        return 0;
}

===========================================
lukep2s의 이미지

^@^@^@^@^@^@^@^@^@^@^@^@^@^@^

vi로 전송된 파일을 열었을때 이런 문자가 들어간 것을 확인할 수 있습니다.

cat 으로 열 경우 정상적으로 출력되어 보입니다.

zmodem을 사용하는 방법은 어렵나요?
참고할 만한 소스나 자료있으면 알려주시면 감사하겠습니다.

절차탁마의 이미지

int get_data ()
{
fp2 = fopen("c","wb"); // 파일을 복사할때는 binary 모드로 여는 편이 좋아요
rFilesize = 72;
while(rFilesize > 0) // 파일 크기만큼 반복
{
fread(serial_buf, buffsize, 1,fd);
printf("1%s1",serial_buf);
write(fp2,serial_buf, sizeof(serial_buf));

rFilesize --;
bzero(serial_buf,MAX);
}

return 0;
}

fread()를 read(), write()를 fwrite() 여기가 좀 이상하네요.
아마도 오타 이신듯..

lukep2s의 이미지

댓글 감사합니다.

파일을 바이너리로 오픈하고
읽거나 쓸때 fread 와 fwrite를 써야 이상 없이 잘 되더라구요

fread 후 write를 한거는 파일에서 열어서 시리얼로 쓰고
read 후 fwrite를 한거는 시리얼에서 열어서 파일로 쓰기 위함입니다.

lipide의 이미지

그냥 한번 쭉 보다가 발견한 것이라 다른 부분은 모르겠습니다만,
일단 발견한 것은 fread함수를 잘못 사용하신 것 같습니다.
fread(변수,변수형의크기,데이터크기,파일핸들러) 와 같이 사용하셔야 할꺼 같은데요;;
joinc에 나온 예제를 올려드리자면..

int a[10];
FILE *stream;
if((stream = fopen ("filename", "r")) != (FILE *)0) 
{
    if (fread(a, sizeof(a), 10, stream) < 10)
    {
        // 읽기 오류 처리
    }
} 
else 
{
    // 열기오류 처리
} 

이런 식이므로..
 fread(serial_buf, buffsize, 1,fd);


 fread(serial_buf, sizeof(char), buffsize, fd);

로 변경해야 될것 같습니다..
lukep2s의 이미지


알려주신대로 사용하니 쓰레기 값이 사라지고
정상적인 줄바꿈도 일어납니다.

테스트를 할때 한개의 컴퓨터에서 시리얼 포트 1 과 시리얼 포트 2를 서로 연결해서 테스트 했습니다. 정상적으로 파일이 전송이 이루어졌습니다.

그런데 QNX ( 리눅스 / 유닉스 계열의 RTOS )와 리눅스가 각각 설치된 다른 컴퓨터에서 시리얼 통신을 했더니 똑같은 프로그램이 다 전송이 안되는 군요

컴 1 : 윈도우에서 vmware로 QNX
컴 2 : 리눅스

다른 컴퓨터끼리 시리얼통신 할 경우 같은 컴에서 테스트 한것에비해
안정적이지 못한 이유에서 인지
vmware 환경 문제 인지
운영체제 문제 인지

알 수 가 없네요
QNX에서도 기본적인 gcc 나 표준 라이브러리를 사용할 수 있는데 말이죠 .

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.