写了一个简单的UDP通讯程序,客户端读文件,把数据写到服务器端;服务端读取数据,写到另一个文件里面。
服务器端代码是这样的:
//#include"unp.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <stdio.h>#include <netinet/udp.h>#include <strings.h>#include <stdlib.h>intmain(int argc, char **argv){intsockfd;struct sockaddr_inservaddr, cliaddr;sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family= AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port= htons(9877);bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));//dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));char buf[500];socklen_t len = sizeof(struct sockaddr);FILE *fp = fopen("/home/charles/code/max-subarray_backup", "w");int count = 0;for(; ;){int nreceived = recvfrom(sockfd, buf, 500, 0, (struct sockaddr *)&cliaddr, &len);if(nreceived > 0){int nwrite = fwrite(buf, sizeof(char), nreceived, fp);if(nwrite != nreceived){printf("expect write: %d, actually write: %d\n", nreceived, nwrite);break;}count += nwrite;printf("write: %d bytes\n", count);fsync(fileno(fp));}else{printf("no data, break\n");fsync(fileno(fp));break;}}fclose(fp);return 0;}客户端代码:
//#include"unp.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <stdio.h>#include <netinet/udp.h>#include <strings.h>#include <string.h>#include <stdlib.h>#include <errno.h>intmain(int argc, char **argv){intsockfd;struct sockaddr_inservaddr;//if (argc != 2)//err_quit("usage: udpcli <IPaddress>");bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(9877);inet_pton(AF_INET, argv[1], &servaddr.sin_addr);sockfd = socket(AF_INET, SOCK_DGRAM, 0);//dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));FILE *fp = fopen("/home/charles/code/max-subarray", "r");int enable_cork = 1, disable_cork = 0;char buf[500];int nread = 0;int count = 0;//setsockopt(sockfd, IPPROTO_UDP, UDP_CORK, &enable_cork, sizeof(enable_cork));while((nread = fread(buf, sizeof(char), 500, fp)) > 0){int nsend = sendto(sockfd, buf, nread, 0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));if(nsend != nread){printf("expected send: %d, actually send: %d err: %s\n", nread, nsend, strerror(errno));break;}count += nsend;printf("write: %d bytes\n", count);}//setsockopt(sockfd, IPPROTO_UDP, UDP_CORK, &disable_cork, sizeof(disable_cork));fclose(fp);exit(0);}测试的时候,发现一个问题,服务端已经读取了所有数据,并且每次 fwrite都是成功的,但是新文件总是比原始文件小。
所以怀疑有数据在buffer里,没有写入到文件。
所以在代码中加了 fsync().
重新编译,测试,,还是有同样的问题。
后来在CSDN论坛上问了一下,有高手建议用fflush()试试。
经过验证,用了fflush()就没有问题了。
看来,fflush()和 fsync()还是不一样的。
fflush()能够把FILE stream的 buffer写入到硬盘,但是 fsync就不行。
use fsync() with not streaming files (integer file descriptors)
use fflush() with file streams.
生命不是一场赛跑,而是一次旅行。比赛在乎终点,而旅行在乎沿途风景。