2011-04-26 91 views
1

我正在升級用C編寫的過濾程序。該程序是爲了從串口接收數據流而稍作修改;然後將其發送到tcp到rs485無線隧道的ip地址。目前該方案依賴於I/O重定向從一個shell腳本 - 這是誘發這樣的:從C程序中寫入IP地址的最簡單方法是什麼?

./packetfilter </dev/ttyS4 >/dev/tcp/10.0.50.101/4660 

殼給我的TCP/IP是免費的。現在我需要stderr和stdout。
將我的串行數據寫入網絡地址最簡單的方法是什麼?

回答

0

重定向到更高的FD,然後使用write(2)

./packetfilter </dev/ttyS4 3>/dev/tcp/10.0.50.101/4660 
+0

這個答案不是C,它是bash。僞造的'/ dev/tcp'是一個bash擴展,它是一個很麻煩的源頭。一些發行版會禁用它,因爲它會產生不一致的shell,並可能在受限制的chroot shell環境中創建安全風險。 – 2011-04-26 01:01:26

+0

@R:這也是OP目前正在使用的內容。 – 2011-04-26 01:01:59

+0

是的,謝謝。但我想通過命令行傳遞IP地址並處理程序中的輸出。我從來沒有做過網絡編程,並會在必要時進行學習。但是,如果有一個簡單的方法來寫入一個字節流到ip - 重複bash目前正在做的 - 這將有助於我知道如何。 – jblange 2011-04-26 01:09:27

3

在C中打開套接字非常容易,但是您發現的大多數代碼都使用醜陋的,不贊成的方法,這使得它看起來很難。下面是正確的方法:

struct addrinfo *ai; 
int fd; 
if (getaddrinfo(host_string, port_string, 0, &ai)) goto failed; 
fd = socket(ai->ai_family, SOCK_STREAM, 0); 
if (connect(fd, ai->ai_addr, ai->ai_addrlen)) goto failed2; 

填寫錯誤處理。

+0

謝謝。這看起來非常可行。我#什麼包括? – jblange 2011-04-26 01:33:45

+1

''和'' – 2011-04-26 03:07:34

+0

如果你完成後不打算保留地址,你也應該調用'freeaddrinfo(ai)',但是你可能想保留它以後需要重新連接的情況。 – 2011-04-26 03:08:52

1

您需要將IP地址以「點」分開,然後形成一個32位整數(假設您只擔心IPV4 - 如果IPV6,您有更多的工作要做)。

每個 「點」 數將成爲YOUT IP addr5ess一個字節 - 使得在十六進制,您在示例地址將成爲0x0A003265

字符(0x0A = 10,00 = 0,0x32 = 50,0x65 = 101,如果我沒有搞砸)

然後傳遞32位整數throputh htons函數,以便它被置於「正確的」(網絡)順序(htons從主機轉換爲網絡字節順序)。將結果插入到您的套接字中,然後全部設置好。

+0

謝謝。我在看這個原型:int getaddrinfo(const char * node,const char * service,const struct addrinfo * hints,struct addrinfo ** res);這是接受地址作爲一個字符串。我錯過了什麼嗎? – jblange 2011-04-26 02:04:35

+1

你給出的答案正是你不應該這樣做的那種古老而醜陋的方式。 IPv4空間今年耗盡。在接下來的幾年中,IPv6支持可能會成爲應用程序的一個成功或失敗問題;如果不支持IPv6,將會有大量的用戶無法使用它們。所以不要去寫這個醜陋的風格代碼,你必須考慮自己轉換二進制地址格式。只需調用'getaddrinfo',一切都爲你完成,IPv4,IPv6甚至IPv7 ;-)都可以毫不費力地工作。 – 2011-04-26 03:10:55

+0

IPv8你的意思是; IPv7將是(?)嚴格的實驗協議。 – 2011-04-26 03:35:22

相關問題