通过串口发送文件

我需要一些帮助通过串行连接发送文件。 我有两个RS232到USB电缆,我正在testing我的代码,使用一个发送数据,另一个接收它。 我有他们两个身体上彼此连接。

于是我写了一些从几个源代码改编的代码,我可以成功地转换一系列的字符。 一个程序接收数据,另一个发送它。 我有两个独立的terminal打开这两个。 find下面的两个代码块:

serialout.c

#include <stdio.h> /* Standard input/output definitions */ #include <string.h> /* String function definitions */ #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ int main() { //writing int writeport = open_port("/dev/ttyUSB0"); char str[] = "hello how are you?"; int n = write(writeport, str, strlen(str)); if (n < 0) fputs("write() of bytes failed!\n", stderr); //closing ports close(writeport); } int open_port(char str[]) { int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK? if (fd == -1) { perror("open_port: Unable to open /dev/ttyS0 - "); } else fcntl(fd, F_SETFL, 0); struct termios options; tcgetattr(fd, &options); //this gets the current options set for the port // setting the options cfsetispeed(&options, B9600); //input baudrate cfsetospeed(&options, B9600); // output baudrate options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode //options.c_cflag &= ~CSIZE; /* mask the character size bits */ options.c_cflag |= CS8; /* select 8 data bits */ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input options.c_iflag &= ~INPCK; // disable parity check options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control options.c_oflag |= OPOST; // ?? choosing processed output options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!) options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!) // settings for no parity bit options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately return (fd); } 

serialin.c

 #include <stdio.h> /* Standard input/output definitions */ #include <string.h> /* String function definitions */ #include <unistd.h> /* UNIX standard function definitions */ #include <fcntl.h> /* File control definitions */ #include <errno.h> /* Error number definitions */ #include <termios.h> /* POSIX terminal control definitions */ int main() { //reading int readport = open_port("/dev/ttyUSB1"); //trying to read one character at a time char buff; int n = 1; while (n > 0) { n = read(readport, &buff, 1); printf("%c", buff, buff); } printf("\n"); //closing ports close(readport); } int open_port(char str[]) { int fd = open(str, O_RDWR | O_NOCTTY | O_NONBLOCK); // ?? NDELAY or NONBLOCK? if (fd == -1) { perror("open_port: Unable to open /dev/ttyS0 - "); } else fcntl(fd, F_SETFL, 0); struct termios options; tcgetattr(fd, &options); //this gets the current options set for the port // setting the options cfsetispeed(&options, B9600); //input baudrate cfsetospeed(&options, B9600); // output baudrate options.c_cflag |= (CLOCAL | CREAD); // ?? enable receicer and set local mode //options.c_cflag &= ~CSIZE; /* mask the character size bits */ options.c_cflag |= CS8; /* select 8 data bits */ options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // choosing raw input options.c_iflag &= ~INPCK; // disable parity check options.c_iflag &= ~(IXON | IXOFF | IXANY); // disable software flow control options.c_oflag |= OPOST; // ?? choosing processed output options.c_cc[VMIN] = 0; // Wait until x bytes read (blocks!) options.c_cc[VTIME] = 0; // Wait x * 0.1s for input (unblocks!) // settings for no parity bit options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; tcsetattr(fd, TCSANOW, &options); //set the new options ... TCSANOW specifies all option changes to occur immediately return (fd); } 

所以我想要做的是发送一个文件。 例如,一个jpeg文件。 有什么方法可以将其转换为字节码并将其重新组装为JPEG格式? 我搜查了一下,但不幸的是发现很less有相关的信息 – 也许我正在寻找错误的条款。

更好的办法是将文件压缩后发送。 最终,我使用gzip压缩jpeg文件,然后通过串行连接发送它们。 感谢大家!

如果你想传输文件,你应该把文件分解成块,并在每个块上使用一个校验和。 然后在您重新加入另一侧的块时验证校验和。

这不是一个新问题。 其他人已经为你解决了。 你应该得到一个现有的可靠的文件传输程序,并通过串行链接运行。

最好的选择是rsync。 这就是GPL,所以如果您正在从事专有工作,许可证可能会阻止您使用它。

另一个不错的选择是XMODEM(或YMODEM或ZMODEM)。 我发现一个带有BSD许可证的XMODEM的C实现,所以你可以肯定地使用它。 这比rsync更小更简单。

http://www.menie.org/georges/embedded/#xmodem

http://en.wikipedia.org/wiki/XMODEM

我也打算建议Z-Modem或X-Modem进行文件传输。 但是你必须明白,文件没有什么特别之处。 就传输计算机和接收终端而言,发送的文件只是一个二进制数据流,不管它是JPEG图像,压缩文件还是文本文件。

你所要做的就是把传入的流写入一个文件,确保它有正确的扩展名,这样可以正确处理。

上面提到的传输协议只添加层以确保整个文件正在发送,并且没有被破坏,但是你可以在第一时间解除它们以理解这个概念。