2012-10-29 56 views
0

我想從我的C++應用程序連接到思科路由器。 需要它來獲得接口狀態。 我的linux站(Ubuntu)和路由器通過串口相連。通過串行接口通過C++連接到思科路由器

從puty或minicom或控制檯連接工作連接。

例如:

[email protected]:/etc/minicom# cu -l /dev/ttyS0 -s 9600 
Connected. 

Router#show int summary 

*: interface is up 
IHQ: pkts in input hold queue  IQD: pkts dropped from input queue 
OHQ: pkts in output hold queue OQD: pkts dropped from output queue 
RXBS: rx rate (bits/sec)   RXPS: rx rate (pkts/sec) 
TXBS: tx rate (bits/sec)   TXPS: tx rate (pkts/sec) 
TRTL: throttle count 

現在我試圖做與C++相同(或C),但讀掛起。

我的C代碼:

#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 
#include <unistd.h> 
#include <iostream> 
#include<stdio.h> 
#include<sys/ioctl.h> 
#include<unistd.h> 
#include<fcntl.h> 
using namespace std; 
int fd1; 
int fd2; 
char *buff, *buffer, *bufptr; 
int wr, rd, nbytes, tries; 

int configure_port(int fd)  // configure the port 
     { 
    struct termios port_settings;  // structure to store the port settings in 
    bzero(&port_settings, sizeof(port_settings)); 
    cfsetispeed(&port_settings, B9600); // set baud rates 
    cfsetospeed(&port_settings, B9600); 

    port_settings.c_cflag &= ~PARENB; // set no parity, stop bits, data bits 
    port_settings.c_cflag &= ~CSTOPB; 
    port_settings.c_cflag &= ~CSIZE; 
    port_settings.c_cflag |= CS8; 

    tcsetattr(fd, TCSANOW, &port_settings); // apply the settings to the port 
    return (fd); 

} 
int main() { 
    fd1 = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); 
    if (fd1 == -1) { 
     perror("open_port: Unable to open /dev/ttyS0 – "); 
    } else { 
     fcntl(fd1, F_SETFL, 0); 
    } 
    printf("Port 1 has been sucessfully opened and %d is the file description\n",fd1); 
    configure_port(fd1); 

wr = write(fd1, "\r", 1); 
cout << " wr status " << wr << endl; 
wr = write(fd1, "\r", 1); 
cout << " wr status " << wr << endl; 
wr = write(fd1, "ena\r", 4); 
cout << " wr status " << wr << endl; 
wr = write(fd1, "show int sum\r", 13); 
cout << " wr status " << wr << endl; 
rd = read(fd1, buff, 50); 
cout << " rd status " << rd << endl; 
cout << rd << endl; 
    return 0; 
} 
+0

設置後是否檢查過'port_settings'?我注意到它沒有初始化爲零... – Useless

+0

我的第一個建議是「嘗試cu」(Linux)或「超級終端」(Windows)。但是你已經這麼做了 - RS232連接是可以的。問:你有沒有嘗試初始化「port_settings」爲零? – paulsm4

+0

@ paulsm4我對此很陌生,你能解釋'port_settings'爲0嗎? –

回答

0

這項工作 - 可能睡眠不見了。

#include <stdio.h> 
#include <string.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <termios.h> 
#include <unistd.h> 
#include <iostream> 
#include<stdio.h> 
#include<sys/ioctl.h> 
#include<unistd.h> 
#include<fcntl.h> 

using namespace std; 

int set_interface_attribs(int fd, int speed, int parity) { 
    struct termios tty; 
    memset(&tty, 0, sizeof tty); 
    if (tcgetattr(fd, &tty) != 0) { 
     printf("err");//error_message("error %d from tcgetattr", errno); 
     return -1; 
    } 

    cfsetospeed(&tty, speed); 
    cfsetispeed(&tty, speed); 

    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;  // 8-bit chars 
    // disable IGNBRK for mismatched speed tests; otherwise receive break 
    // as \000 chars 
    tty.c_iflag &= ~IGNBRK;   // ignore break signal 
    tty.c_lflag = 0;    // no signaling chars, no echo, 
            // no canonical processing 
    tty.c_oflag = 0;    // no remapping, no delays 
    tty.c_cc[VMIN] = 0;   // read doesn't block 
    tty.c_cc[VTIME] = 5;   // 0.5 seconds read timeout 

    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 

    tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, 
            // enable reading 
    tty.c_cflag &= ~(PARENB | PARODD);  // shut off parity 
    tty.c_cflag |= parity; 
    tty.c_cflag &= ~CSTOPB; 
    tty.c_cflag &= ~CRTSCTS; 

    if (tcsetattr(fd, TCSANOW, &tty) != 0) { 
     printf("err");//error_message("error %d from tcsetattr", errno); 
     return -1; 
    } 
    return 0; 
} 

void set_blocking(int fd, int should_block) { 
    struct termios tty; 
    memset(&tty, 0, sizeof tty); 
    if (tcgetattr(fd, &tty) != 0) { 
     printf("err");//error_message("error %d from tggetattr", errno); 
     return; 
    } 

    tty.c_cc[VMIN] = should_block ? 1 : 0; 
    tty.c_cc[VTIME] = 5;   // 0.5 seconds read timeout 

    if (tcsetattr(fd, TCSANOW, &tty) != 0) 
     printf("err");//error_message("error %d setting term attributes", errno); 
} 

int main(int argc, char **argv) { 
    char *portname = "/dev/ttyS0"; 
    int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); 
    if (fd < 0) { 
     printf("err");//error_message("error %d opening %s: %s", errno, portname,strerror(errno)); 
     return -1; 
    } 

    set_interface_attribs(fd, B9600, 0); // set speed to 115,200 bps, 8n1 (no parity) 
    set_blocking(fd, 0);    // set no blocking 
    write(fd, "\r", 1);   // send 7 character greeting 
    write(fd, "\r", 1); 
    usleep(100000); 
    char buf[1000]; 
    write(fd, "ena\r", 4); 
    memset(&buf, 0, sizeof buf); 
    usleep(100000); 
    write(fd, "show int sum\r", 15); 
    sleep(1); 
    memset(&buf, 0, sizeof buf); 
    int n = read(fd, buf, sizeof buf); // read up to 100 characters if ready to read 
    cout << " n " << n << endl; 
    cout << " buf " << buf << endl; 
    close(fd); 
} 
+1

依靠睡眠或其他延遲導致捕獲完整回覆是一個不可靠的實現,如果連接的設備有一天會更慢地回覆,可能會中斷實現。您希望循環讀取,直到您通過指定的終止字符/條件收到完整回覆,或者使用讀取函數讀取直到出現此類情況(或超時或其他錯誤)爲止。 –

+0

@ChrisStratton您可以參考「超時讀取」 –

+0

查看select()或相關的系統調用,作爲實現具有超時的數據檢查的手段,只有在它們指示數據可用時才能讀取。或者,您可以將端口置於非阻塞模式並定期輪詢(但要注意,在緊密的循環中繁忙等待會消耗大量的CPU並降低其他任務的性能)。您似乎已經設置了非阻塞I/O,因此縮短睡眠時間並進行循環,直到收到完整的消息爲止 - 但要注意收集一條消息的結尾和另一條消息的一開始讀取。 –

0

您還沒有修改之前先歸零你port_settings結構。這肯定是一個錯誤,儘管它可能不是你問題的根源。您是否嘗試過構建intnernet上的幾十個「termios示例程序」以供比較?

+0

我嘗試過zeroieng,但是讀取結果是掛起的。我從互聯網複製我的例子。我也試過這個例子 - http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c,但讀仍然掛起 –

+0

你找不到*任何*您的串口工作示例?這似乎很奇怪。嘗試運行minicom時運行'stty

0

您應該使用SNMP獲取接口狀態/統計信息,而不是連接到串行控制檯。

這是確切的目的SNMP是爲什麼設計的。

+0

管理控制計算機不能與路由器(安全)進行網絡連接,因此需要與串行連接。 –