UDP通讯中数据不能写入文件的问题
2015-03-22 13:50
225 查看
写了一个简单的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
use
服务器端代码是这样的:
//#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.
相关文章推荐
- javascript操作写入txt文件及消息: Automation 服务器不能创建对象问题
- 使用jxl.jar处理excel文档,创建的excel文件不能写入数据
- 解决crontab定时任务不能写入文件的问题
- 关于kafka内存溢出,和数据不能写入问题
- android OutputStream向sd卡中文件写入操作立即关机数据清0问题
- 将数据写入到CSV文件中--出现“科学计数法”问题,已解决
- error:fprintf不能向文件中写入数据
- 解决磁盘只读、介质受写入保护或者不能写入和删除数据的问题
- Redis 中文入库成功,读取数据写入文件乱码问题
- android 设备写入文件,立即断电重启后,文件丢失,数据没有保存问题
- 关于.net网站 js文件更新 但js代码不能写入的问题
- RandomAccessFile 类中整型 int 数据写入文件问题
- java读写properties文件,解决系统找不到指定路径,解决写入后读取正常,但文件数据未更新问题
- Android Wear开发 - 数据通讯 - 第四节 : 数据封装(解决不能序列化问题)
- andorid 解压zip文件、android中文文件存放问题、asset里不能放中文名文件的解决方法、用File读asset的路径的问题、把asset的文件写入机器
- 关于win7/8下不能写入文件的问题
- 动态创建文本文件并写入数据 避免正由另一进程使用,因此该进程无法访问该文件。的问题
- 修改TEST_UDP_PROACTOR不能连续接受客户数据的问题
- Python Scrapy学习之pipelines不能保存数据到文件问题
- ”outlook不能打开文件夹集,不是outlook数据文件 ost“问题的结局