我有一个现有的C程序,它使用以下命令将许多消息打印到标准错误:
fprintf(stderr, ...
我想修改此程序,以便这些消息也通过Internet上的TCP连接发送出去。 (我已经创建了一个SOCK_STREAM套接字。)什么是fprintf格式化消息的最佳方式,然后通过Internet发送出去?
当然,在我发送消息之前,我首先需要知道它有多长,所以我可以先将长度发送给客户端,这样客户端就会知道要读取多少字节...
任何想法都会非常感激!
答案 0 :(得分:3)
连接套接字后,可以使用套接字文件描述符上的fdopen()
将其作为流打开。这将为您提供FILE *
,您可以将其传递到fprintf()
代替stderr
。
答案 1 :(得分:1)
我建议你将输出调用包装在一个变量参数函数中(它的printf系列函数如何工作)并从那里做所有事情。例如,它可能看起来像:
int multi_log(FILE * stream, int fd, const char * fmt, ...) {
char buff[BUFF_MAX] = {0};
int len = 0;
va_list args;
va_start (args, fmt);
len = vsnprintf (buff, BUFF_MAX, fmt, args);
va_end (args);
fputs (buff, stream);
write (fd, buff, len);
}
这样您就可以根据需要添加和/或删除功能。
注意事项适用于使用vsnprintf
返回的尺码,仔细阅读手册页
答案 2 :(得分:0)
我认为您需要查看sprintf
或(更好)需要您提供显式输出缓冲区大小的变体。
答案 3 :(得分:0)
你使它变得比它需要的更难。如果您要发送二进制数据,并且客户端需要识别消息边界,那么是的,您可能希望首先发送消息长度,或者使用某种" framing"描绘消息边界。但在这种情况下,你不需要那样做。您可以使用上面建议的方法将消息文本写出到套接字。
另一方面,对等体可以坐在循环读取文本中,直到套接字关闭。如果希望阅读器逐行处理文本,可以使用换行符标记每行的结尾。然后,读者可以扫描收到的文本,查找换行符。
唯一可能棘手的是,因为TCP是面向字节而不是面向消息的,所以读者不会总是以与发送者发送的文本相同的大小来获取文本。 (通常你会这样做,但不能保证。)所以你的读者需要能够处理从套接字中读取一条线的一部分,或者多条线组合在一起的情况。只要您编写可能发生的可能性,这不是一个大问题。