0

我对这段代码有疑问。问题是我必须用这个期货开发一个客户端-服务器模型:

  1. 客户端类型:“GETfile_name.txt”;
  2. 服务器接收请求并发送文件大小;
  3. 服务器发送文件;

问题是服务器没有将文件发送到客户端。感谢大家的帮助。

代码是这样的:

服务器:

f = fopen(file_name,"r");

/* file's size */
fseek(f,0L,SEEK_END);
size = ftell(f);
fseek(f,0L,SEEK_SET);

/* convert int to string */
sprintf(file_size,"%d",size); 

/* send file's size to the client */
Send(s,file_size,sizeof(file_size)); 

/* send file to the client */
buffer = (char *) malloc(sizeof(char)*size);  
bzero(buffer,sizeof(char)*size);
x = fread(binoltro,sizeof(char),sizeof(char)*dimensione,f);
Send(s,binoltro,x);

客户:

/* wait file's size */
recv(s,buffer,MAX,0); 
printf("Remote server will send: %s Bytes\n",buffer);
size = atoi(buffer);

/* execute malloc */
buffer = (char *) malloc(sizeof(char)*size);
bzero(buffer,size*sizeof(char));

Recv(s,buffer,size*sizeof(char));
fwrite(buffer,sizeof(char),size*sizeof(char),f);
printf("File: %s",buffer);

/* clean the buffer */
bzero(buffer,MAX);

/* do free */
free(buffer);
fclose(f);

和:

int Recv (int s, char *ptr, size_t maxlen){
size_t n;
ssize_t nread;
char c;

for (n=1; n<maxlen; n++)
{
    nread=recv(s, &c, 1, 0);
    if (nread == 1)
    {
        *ptr++ = c;
        if (c == '\n')
            break;
    }
    else if (nread == 0)    
    {
        *ptr = 0;
        return (n-1); 
    }
    else
        return (-1); 
}
*ptr = 0;
return (n);
}

和:

int Send(int s, char *ptr, size_t nbytes){
size_t  nleft;
ssize_t nwritten;

for (nleft=nbytes; nleft > 0; )
{
    nwritten = send(s, ptr, nleft, 0);
    if (nwritten <=0)
        return (nwritten);
    else
    {
        nleft -= nwritten;
        ptr += nwritten;
    }
}
return (nbytes - nleft); 
}
4

1 回答 1

0

我看到的问题是您的 Recv() 函数在收到 '\n' 或没有更多数据或达到 maxlen 时会中断。在您的客户端收到文件长度的最后一个字节后,这些条件都不匹配,因此它会继续读取并且文件数据会丢失。

我建议您使用以下方法将文件长度填充为固定位数(例如 10)

sprintf( file_size, "%010s", size );

并使用修改后的 Recv() 函数,如下所示:

int Recv (int s, char *ptr, size_t nbytes ){
    size_t n;
    ssize_t nread;


    while( nbytes > 0 ) {
        if( (nread = recv( s, ptr, nbytes, 0 )) <= 0 )
            return -1; /* Error */

        ptr += nread;
        nbytes -= nread;
    }
    +ptr = '\0';
    return 0; /* OK */
}

然后您的客户可以首先使用读取文件大小

Recv( s, buffer, 10 )

然后使用数据

Recv( s, ..., atoi( buffer ) )

确保分配文件大小 + 1,因为 Recv() 添加了 '\0'

于 2013-06-10T15:48:23.223 回答