简体   繁体   English

socket c客户端没有收到字符串

[英]socket c client doesn't receive string

This is the snippet of client code: 这是客户端代码的片段:

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;

And this is the snippet of the server code: 这是服务器代码的片段:

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;

This is the expected behaviour: 这是预期的行为:

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

But this is the real behaviour: 但这是真实的行为:

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

So the problem is that the client doesn't receive "File has been sent". 所以问题是客户端没有收到“文件已被发送”。 I've checked if the problem is server's side but it isn't (in fact the server send the string) 我已检查问题是否是服务器端但不是(事实上服务器发送字符串)

(based on the comments above) -- the thing to realize is that TCP communication is 100% stream based, with no built-in framing. (基于上面的评论) - 要实现的是TCP通信是100%基于流的,没有内置的框架。 That means that all the TCP layer does is make sure that the receiver receives the bytes in the same order that the sender sent them -- but it does not guarantee that the bytes will be received in the same intervals as they were sent. 这意味着所有TCP层都确保接收方以发送方发送的相同顺序接收字节 - 但保证字节将以与发送时相同的间隔接收。 (For example, if you send() 10 bytes, then 20 bytes, then 50 bytes, the receiver might receive all 80 bytes at once, or 63 bytes followed 17 bytes, or any other combination of recv()s that sum up to 80 bytes total). (例如,如果发送()10个字节,然后20个字节,然后50个字节,接收器可能一次接收所有80个字节,或者63个字节接着17个字节,或者汇总到的任何其他recv()的组合总共80个字节)。

Therefore in order to send multiple separate items in such a way that the receiver can interpret them correctly, you need to define your own rules for framing the data. 因此,为了以接收器可以正确解释它们的方式发送多个单独的项目,您需要定义自己的规则来构建数据。 In your case you need to send n bytes of file data, followed by a string, and what your receiving program needs to know is how many bytes of file data to expect. 在您的情况下,您需要发送n个字节的文件数据,后跟一个字符串,接收程序需要知道的是文件数据的字节数。 That way, once it has received (that many) bytes, it knows the remaining bytes are string data and won't just write them to the file. 这样,一旦它收到(那么多)字节,它就知道剩下的字节是字符串数据,而不只是将它们写入文件。

My suggestion would be to send the file's size first (either as a 4-byte integer, or an 8-byte long if you need to support file sizes greater than 4 gigabytes). 我的建议是首先发送文件的大小(如果需要支持大于4千兆字节的文件大小,则为4字节整数或8字节长)。 Then the receiving code would be like this: 然后接收代码将是这样的:

  1. Receive 4 bytes 接收4个字节
  2. Interpret those four bytes as an integer (you may want to pass this value through htonl() on the sender and ntohl() on the receiver, in order to avoid possible endian-ness issues here) 将这四个字节解释为整数(您可能希望通过发送方的htonl()和接收方的ntohl()传递此值,以避免此处可能存在的字符串问题)
  3. Receive N bytes and write them to the file 接收N个字节并将其写入文件
  4. Receive any remaining bytes as a string. 接收任何剩余字节作为字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM