我正在尝试将一些xml数据写入C中的套接字。我可以使用以下命令将xml字符串打印到屏幕:
printf("<tag1>%d</tag1>"
"<tag2>%s</tag2>"
"<tag3>%s</tag3>"
"<tag4>%d</tag4>",
int1,
str2,
str3,
int4);
我尝试将snprintf
字符串写入缓冲区(char[]
),然后将缓冲区的内容写入套接字,而不是打印到stdout。不幸的是,我想这里缓冲区在写str2
或str3
期间可能已满,可能甚至不足以包含任何一个字符串。
使用snprintf
可以很容易地检查我是否能够将所有数据写入缓冲区,但是在将缓冲区内容发送到套接字后我不能继续停止。
基本上:如果格式化的字符串超过64个字节,是否有功能允许我将"%d%s%s%d"
的64个字节发送到套接字?
如果此功能不存在,我对您建议的解决方法感兴趣(如果有帮助,您可以假设%s
字段由一个试图溢出缓冲区的邪恶机器人填充,无论尺寸)。
答案 0 :(得分:4)
在Linux上至少使用GNU libc,您可以使用asprintf(3)(提供malloc
- ed字符串)或dprintf(3)(打印到文件描述符中)。< / p>
您还可以(并且更便携地)fdopen(3)套接字文件描述符,然后fprintf(3) 和fflush(3) 。您可以使用setvbuf(3)配置缓冲。
fileno(3)也很有用......
BTW,snprintf(3)返回所需字节的数量。所以你可以编码
char tinybuf[100];
char* buf = tinybuf;
int nbytes= snprintf(tinybuf, sizeof(tinybuf),
"<tag at='%d'>%s</tag>", num, string);
if (nbytes >= sizeof(tinybuf)) { // rarely happens
char *buf = malloc(nbytes+1);
if (!buf) { perror("malloc"); abort(); };
snprintf(buf, nbytes+1,
"<tag at='%d'>%s</tag>", num, string);
};
int off=0;
while (nbytes>0) {
int nbw=write(sock, buf+off, nbytes);
if (nbw>0) { off += nbw; nbytes -= nbw; };
else if (nbw<0 && errno != EINTR) { perror("write"); abort(); };
};
if (buf != tinybuf) free(buf);
这会避免在malloc
适合的常见情况下free
和tinybuf
...
答案 1 :(得分:3)
如何将fprintf
与套接字描述符一起使用?
类似的东西:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
FILE *fd = fdopen(sockfd, "w")
fprintf(fd, "<tag1>%d</tag1>"
"<tag2>%s</tag2>"
"<tag3>%s</tag3>"
"<tag4>%d</tag4>",
int1,
str2,
str3,
int4);
fflush(fd);