通过TCP连接发送格式化消息

时间:2009-12-06 03:55:28

标签: c sockets tcp printf

我有一个现有的C程序,它使用以下命令将许多消息打印到标准错误:

fprintf(stderr, ...

我想修改此程序,以便这些消息也通过Internet上的TCP连接发送出去。 (我已经创建了一个SOCK_STREAM套接字。)什么是fprintf格式化消息的最佳方式,然后通过Internet发送出去?

当然,在我发送消息之前,我首先需要知道它有多长,所以我可以先将长度发送给客户端,这样客户端就会知道要读取多少字节...

任何想法都会非常感激!

4 个答案:

答案 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是面向字节而不是面向消息的,所以读者不会总是以与发送者发送的文本相同的大小来获取文本。 (通常你会这样做,但不能保证。)所以你的读者需要能够处理从套接字中读取一条线的一部分,或者多条线组合在一起的情况。只要您编写可能发生的可能性,这不是一个大问题。