写了一个简单的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>
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, 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>
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
// 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.