C 如何使用小缓冲区将格式化字符串发送到套接字?
我正在尝试将一些xml数据写入C中的套接字。我可以使用以下命令将xml字符串打印到屏幕上:C 如何使用小缓冲区将格式化字符串发送到套接字?,c,sockets,printf,C,Sockets,Printf,我正在尝试将一些xml数据写入C中的套接字。我可以使用以下命令将xml字符串打印到屏幕上: printf("<tag1>%d</tag1>" "<tag2>%s</tag2>" "<tag3>%s</tag3>" "<tag4>%d</tag4>", int1, str2, str3, int4); p
printf("<tag1>%d</tag1>"
"<tag2>%s</tag2>"
"<tag3>%s</tag3>"
"<tag4>%d</tag4>",
int1,
str2,
str3,
int4);
printf(“%d”
%s
%s
“%d”,
int1,
str2,
str3,
int4);
我没有打印到stdout,而是尝试将该字符串snprintf
写入缓冲区(char[]
),然后将缓冲区的内容写入套接字。不幸的是,我认为在写入str2
或str3
的过程中,缓冲区可能已满,甚至可能不够大,无法包含任何字符串
使用snprintf
可以很容易地检查我是否能够将所有数据写入缓冲区,但在将缓冲区内容发送到套接字后,不容易继续执行我中断的操作
基本上:如果格式化字符串长度超过64字节,是否有一种功能可以让我一次将64字节发送到套接字
如果此功能不存在,我对您建议的解决方法感兴趣(如果有帮助,您可以假设%s
字段由一个邪恶的机器人填充,该机器人试图溢出您的缓冲区,而不管大小)。在Linux上,至少您可以使用(这会给出malloc
-ed字符串)或(打印到文件描述符中)
您还可以(更方便地)使用套接字文件描述符,然后和使用它
也很有用
顺便说一句,正在返回所需的字节数。因此您可能需要编写代码
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);
chartinybuf[100];
char*buf=tinybuf;
int nbytes=snprintf(tinybuf,sizeof(tinybuf),
“%s”,num,字符串);
如果(nbytes>=sizeof(tinybuf)){//很少发生
char*buf=malloc(n字节+1);
如果(!buf){perror(“malloc”);abort();};
snprintf(基本单位,单位字节+1,
“%s”,num,字符串);
};
int off=0;
而(n字节>0){
int nbw=写入(sock,buf+off,nbytes);
如果(nbw>0){off+=nbw;nbytes-=nbw;};
如果(nbw使用带有套接字描述符的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);
intsockfd=socket(AF_INET,SOCK_STREAM,0);
文件*fd=fdopen(sockfd,“w”)
fprintf(fd,“%d”
%s
%s
“%d”,
int1,
str2,
str3,
int4);
fflush(fd);
使用snprintf
。如果缓冲区不够大,请放大缓冲区,然后再次调用snprintf
。@BasileStarynkevitch感谢提醒!谢谢!如果我所有的fprintf
都换行终止,是否仍需要使用fflush
?不确定,但他们不介意任何人。显式比隐式好:)是的,您需要使用fdopen
(或setvbuf
在fdopen
之后进行一次fflush
)。@PauloBu直接使用dprintf
怎么样?可以吗?