Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使用小缓冲区将格式化字符串发送到套接字?_C_Sockets_Printf - Fatal编程技术网

C 如何使用小缓冲区将格式化字符串发送到套接字?

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

我正在尝试将一些xml数据写入C中的套接字。我可以使用以下命令将xml字符串打印到屏幕上:

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
怎么样?可以吗?