2013-05-01 69 views
1

我正在openSUSE 12.3中開發一個C++應用程序,它的一個部分是負責通過Socket(在局域網內)向設備發送數據。我使用此代碼C++在Linux下的Socket編程

int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *printer;  
portno = 9100; 

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if(sockfd < 0) error("ERROR opening socket\n"); 
printer = gethostbyname("100.0.69.23"); 
if(printer == NULL) error("No such device on 100.0.69.23\n"); 
//set bit set to zero 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *) printer->h_addr, (char *) &serv_addr.sin_addr.s_addr, printer-  >h_length); 

serv_addr.sin_port = htons(portno); 

if(connect(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) 
    {error("ERROR connecting"); 
      return; 
    } 

n = write(sockfd, data, datalenght); 
if(n < 0) error("ERROR sending command to printer"); 
n = read(sockfd, buffer, 200); 

我認爲的代碼是正確的,但連接函數返回-1,並似乎無法連接到該設備(打印機)。這段代碼是用openSUSE 11編寫的,工作正常,我可以向設備發送/接收數據,但是當我將它複製/粘貼到新系統(openSUSE 12.3)時,它使我無法連接。我ping了正在使用的特定IP的結果,表明設備可通過LAN到達

+0

您發送給打印機的字節數是多少? – suspectus 2013-05-01 12:55:56

+0

您在初始化之前檢查「打印機」,然後再檢查。那不好。 – 2013-05-01 12:59:09

+2

另外,connect()返回的錯誤究竟是什麼?它必須有你的問題的答案的90%。 – 2013-05-01 12:59:35

回答

1

如前所述,在初始化之前您正在檢查printer == NULL。我覺得你的意思,而不是以下:

sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) error("ERROR opening socket\n"); 
printer = gethostbyname("100.0.69.23"); 
... 

而且代碼的結構似乎表明,當你想發送命令到打印機你connect()write()然後read(),如果你永遠只能是OK發送一個命令,但如果您發送多個命令則不太理想。在後一種情況下,您想將connect()write()分開,因爲連接起來相當昂貴,所以您只需要一次。

+0

你是對的,但問題是現在的另一個問題,目前我無法連接到設備。解決主要問題後,我會改變代碼如你所說,並分開連接和寫入。當連接func失敗時sockfd值大於0 – Areff 2013-05-01 13:17:21

2

我想你應該考慮hostent返回的可能性gethostbyname功能可能有AF_INET6地址系列(在這種情況下,它將是IPv6而不是IPv4地址)。

http://linux.die.net/man/3/gethostbyname

所以,你既可以使用GNU擴展功能gethostbyname2功能,將允許您指定的地址族。

printer = gethostbyname2("100.0.69.23", AF_INET); 

或者相反,您可以使用getaddrinfo功能,如gethostbyname功能被認爲是過時的,由文檔。