2011-04-26 65 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

相关问题