当前位置: 技术问答>linux和unix
求助:c语言socket文件传输中buffer缓存出现的问题
来源: 互联网 发布时间:2016-12-18
本文导语: 新手求助:在socket文件传输中为什么每次读取buffer都会在数据后面出现一个(filename)即文件名 我每次读取buffer都会将buffer里面的内容先清空~! c/c++客户端代码: #include #include #include #include #include #incl...
新手求助:在socket文件传输中为什么每次读取buffer都会在数据后面出现一个(filename)即文件名
我每次读取buffer都会将buffer里面的内容先清空~!
c/c++客户端代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define portnumber 3333
#define FILE_NAME_MAX_SIZE 512
int main(int argc, char *argv[])
{
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr;
struct hostent *host;
FILE *fd;
if(argc!=2)
{
fprintf(stderr,"Usage:%s hostname an",argv[0]);
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"Gethostname errorn");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
fprintf(stderr,"Socket Error:%san",strerror(errno));
exit(1);
}
/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr)); // 初始化,置0
server_addr.sin_family=AF_INET; // IPV4
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址
/* 客户程序发起连接请求 */
//while(1)
{
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%san",strerror(errno));
exit(1);
}
char filename[FILE_NAME_MAX_SIZE];
bzero(filename,FILE_NAME_MAX_SIZE);
printf("please input which file you want to downlop:n");
scanf("%s",&filename);
printf("%sn",filename);
bzero(buffer,BUFFER_SIZE);
strcat(buffer,filename);
printf("%sn",buffer);
send(sockfd,buffer,BUFFER_SIZE,0);
fd=fopen(filename,"a");
int nbytes=0;
while(1)
{
bzero(buffer,BUFFER_SIZE);
nbytes=recv(sockfd,buffer,sizeof(buffer),0);
printf("nbytes:%dn",nbytes);
printf("buffer:%sn",buffer);
printf("strlen(buffer):%dn",strlen(buffer));
if(strcmp(buffer,"1")==0)
{
break;
}
write(fd,buffer,sizeof(buffer));
}
printf("fjdjjsdfjafjdfjn");
fclose(fd);
/* 结束通讯 */
close(sockfd);
}
}
这是服务器代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define portnumber 3333
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
int n;
FILE *fd;
char buffer[BUFFER_SIZE];
char filename[FILE_NAME_MAX_SIZE];
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%sna",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%sna",strerror(errno));
exit(1);
}
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%sna",strerror(errno));
exit(1);
}
while(1)
{
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%sna",strerror(errno));
exit(1);
}
fprintf(stderr,"Server get connection from %sn",inet_ntoa(client_addr.sin_addr)); int length;
bzero(buffer,BUFFER_SIZE);
if((length=recv(new_fd,buffer,BUFFER_SIZE,0))h_addr); // IP地址
/* 客户程序发起连接请求 */
if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) {
fprintf(stderr,"Connect Error:%san",strerror(errno));
exit(1);
}
char filename[FILE_NAME_MAX_SIZE];
bzero(filename, FILE_NAME_MAX_SIZE);
printf("please input which file you want to downlop:n");
scanf("%s", filename); //del &
printf("%sn", filename);
bzero(buffer, BUFFER_SIZE);
strcat(buffer, filename);
printf("%sn", buffer);
send(sockfd, buffer, BUFFER_SIZE, 0);
fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int nbytes = 0;
int c = 1;
while(1) {
bzero(buffer,BUFFER_SIZE);
nbytes = recv(sockfd, buffer, BUFFER_SIZE, 0);
if (nbytes == 0)
break;
//buffer[nbytes] = ''; //这个不需要了, 因为下面的write函数不需要''作为分界符
if (write(fd, buffer, nbytes) != nbytes)
fprintf(stderr, "write error");
}
printf("fjdjjsdfjafjdfjn");
close(fd);
/* 结束通讯 */
close(sockfd);
}
server.c
先前的不能传图片文件,因为图片格式包含不可见字符, fgets和fprintf函数没办法处理, 现在改成read,write函数直接对文件进行二进制处理,应该没问题了, 你再试试看
我每次读取buffer都会将buffer里面的内容先清空~!
c/c++客户端代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define portnumber 3333
#define FILE_NAME_MAX_SIZE 512
int main(int argc, char *argv[])
{
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr;
struct hostent *host;
FILE *fd;
if(argc!=2)
{
fprintf(stderr,"Usage:%s hostname an",argv[0]);
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"Gethostname errorn");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) {
fprintf(stderr,"Socket Error:%san",strerror(errno));
exit(1);
}
/* 客户程序填充服务端的资料 */
bzero(&server_addr,sizeof(server_addr)); // 初始化,置0
server_addr.sin_family=AF_INET; // IPV4
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址
/* 客户程序发起连接请求 */
//while(1)
{
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%san",strerror(errno));
exit(1);
}
char filename[FILE_NAME_MAX_SIZE];
bzero(filename,FILE_NAME_MAX_SIZE);
printf("please input which file you want to downlop:n");
scanf("%s",&filename);
printf("%sn",filename);
bzero(buffer,BUFFER_SIZE);
strcat(buffer,filename);
printf("%sn",buffer);
send(sockfd,buffer,BUFFER_SIZE,0);
fd=fopen(filename,"a");
int nbytes=0;
while(1)
{
bzero(buffer,BUFFER_SIZE);
nbytes=recv(sockfd,buffer,sizeof(buffer),0);
printf("nbytes:%dn",nbytes);
printf("buffer:%sn",buffer);
printf("strlen(buffer):%dn",strlen(buffer));
if(strcmp(buffer,"1")==0)
{
break;
}
write(fd,buffer,sizeof(buffer));
}
printf("fjdjjsdfjafjdfjn");
fclose(fd);
/* 结束通讯 */
close(sockfd);
}
}
这是服务器代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define portnumber 3333
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
int n;
FILE *fd;
char buffer[BUFFER_SIZE];
char filename[FILE_NAME_MAX_SIZE];
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket error:%sna",strerror(errno));
exit(1);
}
bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Bind error:%sna",strerror(errno));
exit(1);
}
if(listen(sockfd,5)==-1)
{
fprintf(stderr,"Listen error:%sna",strerror(errno));
exit(1);
}
while(1)
{
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
{
fprintf(stderr,"Accept error:%sna",strerror(errno));
exit(1);
}
fprintf(stderr,"Server get connection from %sn",inet_ntoa(client_addr.sin_addr)); int length;
bzero(buffer,BUFFER_SIZE);
if((length=recv(new_fd,buffer,BUFFER_SIZE,0))h_addr); // IP地址
/* 客户程序发起连接请求 */
if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) {
fprintf(stderr,"Connect Error:%san",strerror(errno));
exit(1);
}
char filename[FILE_NAME_MAX_SIZE];
bzero(filename, FILE_NAME_MAX_SIZE);
printf("please input which file you want to downlop:n");
scanf("%s", filename); //del &
printf("%sn", filename);
bzero(buffer, BUFFER_SIZE);
strcat(buffer, filename);
printf("%sn", buffer);
send(sockfd, buffer, BUFFER_SIZE, 0);
fd = open(filename, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
int nbytes = 0;
int c = 1;
while(1) {
bzero(buffer,BUFFER_SIZE);
nbytes = recv(sockfd, buffer, BUFFER_SIZE, 0);
if (nbytes == 0)
break;
//buffer[nbytes] = ''; //这个不需要了, 因为下面的write函数不需要''作为分界符
if (write(fd, buffer, nbytes) != nbytes)
fprintf(stderr, "write error");
}
printf("fjdjjsdfjafjdfjn");
close(fd);
/* 结束通讯 */
close(sockfd);
}
server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define portnumber 3333
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size;
int nbytes;
int n;
int fd; //改成用文件描述符, 不用FILE
char buffer[BUFFER_SIZE];
char filename[FILE_NAME_MAX_SIZE];
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1) {
fprintf(stderr,"Socket error:%sna",strerror(errno));
exit(1);
}
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(portnumber);
if(bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "Bind error:%sna", strerror(errno));
exit(1);
}
if(listen(sockfd,5) == -1) {
fprintf(stderr, "Listen error:%sna", strerror(errno));
exit(1);
}
while(1) {
sin_size = sizeof(struct sockaddr_in);
if((new_fd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size)) == -1) {
fprintf(stderr, "Accept error:%sna", strerror(errno));
exit(1);
}
fprintf(stderr, "Server get connection from %sn", inet_ntoa(client_addr.sin_addr));
int length;
bzero(buffer, BUFFER_SIZE);
if((length = recv(new_fd,buffer,BUFFER_SIZE,0)) 0) { //通过read函数读文件
if (send(new_fd, buffer, nbytes, 0) != nbytes)
fprintf(stderr, "send error");
}
close(fd);
close(new_fd);
}
close(sockfd);
/* 结束通讯 */
exit(0);
}
先前的不能传图片文件,因为图片格式包含不可见字符, fgets和fprintf函数没办法处理, 现在改成read,write函数直接对文件进行二进制处理,应该没问题了, 你再试试看
|
这是个文件传输程序吗?我放假前刚好写过,当时有两个主要错误。其中一个跟lz的很像,发送和接受的大小不一样。
检查一下两边的缓冲区大小,包括send、recv和read、write的,多1少1都不好,一定要把各种边缘情况考虑清楚。我当时把缓冲区大小修改了1就没有错误了。
lz的代码没细看,自己仔细检查一下。要是一直没解决的话,等我用linux的时候,我把我的代码贴出来。
检查一下两边的缓冲区大小,包括send、recv和read、write的,多1少1都不好,一定要把各种边缘情况考虑清楚。我当时把缓冲区大小修改了1就没有错误了。
lz的代码没细看,自己仔细检查一下。要是一直没解决的话,等我用linux的时候,我把我的代码贴出来。
|
代码可能对,但是解释有问题。
标准流没有二进制之分。lz在网络编程时用标准流是个错误。标准流有自己的缓冲区,可能在socket编程时带来不可预知的错误。
网络编程时,应该只用read、write等函数,或者自己提供缓冲区。同时控制好缓冲区大小。