0

这是客户端代码片段:

connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

strcpy(Buffer, filename);

send(DescrittoreClient, Buffer, strlen(Buffer), 0);
fd = open(filename, O_CREAT | O_WRONLY,0644);

while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) != 0) {
    write(fd, Buffer, nread);
    memset(Buffer,0,sizeof(Buffer));
}
int gg;
while( (gg = recv(DescrittoreClient, Buffer, sizeof(Buffer), 0)) == -1) continue;
printf("%d\n", gg);
printf("Risposta del server: %s\n", Buffer);

close(DescrittoreClient);
return EXIT_SUCCESS;

这是服务器代码的片段:

while(1){

    rc = recv(DescrittoreClient, filename, sizeof(filename), 0);

    fd = open(filename, O_RDONLY);

    fstat(fd, &stat_buf);

    offset = 0;
    rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size);
    if (rc != stat_buf.st_size) {
        fprintf(stderr, "incomplete transfer from sendfile: %d of %d bytes\n", rc, (int)stat_buf.st_size);
        exit(1);
    }
    strcpy(Buffer, "Dati inviati correttamente");
    if( (send(DescrittoreClient, Buffer, strlen(Buffer), 0)) == -1){
        printf("Errore nell'invio della stringa\n");
        close(DescrittoreClient);
        close(fd);
        exit(1);
    }

}
close(DescrittoreServer);
return EXIT_SUCCESS;

这是预期的行为:

Client --Give me file X--> Server
Server --send the file X--> Client
Server -->send string "File has been sent"--> Client

但这是真正的行为:

Client --Give me file X--> Server
Server --send the file X--> Client
Server -->_NOTHING_--> Client

所以问题是客户端没有收到“文件已发送”。我检查了问题是否出在服务器端,但不是(实际上是服务器发送了字符串)

4

1 回答 1

2

(基于上面的评论)——要实现的是 TCP 通信是 100% 基于流的,没有内置框架。这意味着 TCP 层所做的所有事情都是确保接收方以与发送方发送它们的顺序相同的顺序接收字节——但它不保证字节将以与发送它们相同的间隔接收。(例如,如果您 send() 10 个字节,然后是 20 个字节,然后是 50 个字节,接收方可能会一次接收所有 80 个字节,或者 63 个字节后跟 17 个字节,或者任何其他的 recv() 组合,总和为总共 80 个字节)。

因此,为了以接收者可以正确解释它们的方式发送多个单独的项目,您需要定义自己的数据框架规则。在您的情况下,您需要发送n个字节的文件数据,后跟一个字符串,而您的接收程序需要知道的是预期有多少字节的文件数据。这样,一旦它接收到(那么多)字节,它就知道剩余的字节是字符串数据,而不会只是将它们写入文件。

我的建议是首先发送文件的大小(如果您需要支持大于 4 GB 的文件大小,则可以作为 4 字节整数或 8 字节长)。那么接收代码会是这样的:

  1. 接收 4 个字节
  2. 将这四个字节解释为整数(您可能希望通过发送方的 htonl() 和接收方的 ntohl() 传递此值,以避免此处可能出现的字节序问题)
  3. 接收 N 个字节并将它们写入文件
  4. 接收任何剩余的字节作为字符串。
于 2012-06-18T16:07:29.787 回答