C套接字,在文件后发送消息,TCP。

时间:2021-04-15 07:37:58

I want to send file through socket and after that i want to send three messages. This code below works, but i have to send first sentence two times. My question is why? Without one sentence1, receiver display sentence2, sentence3 and sentence3. What is wrong with this code? I'm using tcp protocol.

我想通过套接字发送文件,然后我想发送三条消息。下面的代码可以,但是我必须把第一个句子发送两遍。我的问题是为什么?没有一个句子,接收者就会显示句子,句子和句子。这段代码有什么问题?我使用tcp协议。

Sender.c

Sender.c

char file_size[256];
struct stat file_stat;
int sent_bytes = 0;
int fd;
int offset;
int remain_data;

fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1)
{
        fprintf(stderr, "Error opening file --> %s", strerror(errno));

        exit(EXIT_FAILURE);
}

/* Get file stats */
if (fstat(fd, &file_stat) < 0)
{
        fprintf(stderr, "Error fstat --> %s", strerror(errno));

        exit(EXIT_FAILURE);
}

fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);

sprintf(file_size, "%d", file_stat.st_size);

write(sck, file_size, 256);

char buffer[1024] = "";


while (1) {
    int bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read == 0) 
        break;

    void *p = buffer;
    while (bytes_read > 0) {
        int bytes_written = write(sck, p, bytes_read);
        if (bytes_written <= 0) {
            // handle errors
        }
        bytes_read -= bytes_written;
        p += bytes_written;

    }
}


char sentence[1024];


write(sck, sentence1, 1024);

write(sck, sentence1, 1024);

write(sck, sentence2, 1024);

write(sck, sentence3, 1024);

Receiver.c

Receiver.c

char buffer[1024] = "";
int sck = *((int*) arg);

int file_size;

read(sck, buffer, 256);
file_size = atoi(buffer);

ssize_t len;
FILE *received_file;
int remain_data = 0;


received_file = fopen("plik.pdf", "w");
if (received_file == NULL)
{
        fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno));

        exit(EXIT_FAILURE);
}

remain_data = file_size;

while (((len = recv(sck, buffer, 1024, 0)) > 0) && (remain_data > 0))
{
        fwrite(buffer, sizeof(char), len, received_file);
        remain_data -= len;
}
fclose(received_file);



read (sck, buffer, 1024);
printf("%s 1\n", buffer);    

read (sck, buffer, 1024);
printf("%s 2\n", buffer);

read (sck, buffer, 1024);
printf("%s 3\n", buffer);

1 个解决方案

#1


2  

Nothing to do with TCP protocol. Your logic is flawed. You are receiving the data and then checking for remain_data. So your sentence1 is received and discarded in the while loop.

与TCP协议无关。你的逻辑是有缺陷的。您正在接收数据,然后检查残余数据。所以你的句子1在while循环中被接收和丢弃。

Move your recv() into the body of while to fix this or change the order in while.

将recv()移动到while体中,以修复它或更改while中的顺序。

while ((remain_data > 0) && ((len = recv(sck, buffer, 1024, 0)) > 0))

In the modified while, you call recv() only if remain_data > 0. recv() is not called if remain_data == 0 (lazy evaluation). So your while loop ends immediately after receiving the file and ready to receive your sentences. In your code, the while loop read the first sentence, then checked remain_data > 0 effectively discarding sentence1

在修改后的while中,您只会在use_data >时调用recv()。recv()不被调用,如果剩下的数据== 0(懒惰的评估)。所以你的while循环在收到文件后立即结束,准备接收你的句子。在您的代码中,while循环读取第一个句子,然后检查残余数据>有效地丢弃了sentence1

#1


2  

Nothing to do with TCP protocol. Your logic is flawed. You are receiving the data and then checking for remain_data. So your sentence1 is received and discarded in the while loop.

与TCP协议无关。你的逻辑是有缺陷的。您正在接收数据,然后检查残余数据。所以你的句子1在while循环中被接收和丢弃。

Move your recv() into the body of while to fix this or change the order in while.

将recv()移动到while体中,以修复它或更改while中的顺序。

while ((remain_data > 0) && ((len = recv(sck, buffer, 1024, 0)) > 0))

In the modified while, you call recv() only if remain_data > 0. recv() is not called if remain_data == 0 (lazy evaluation). So your while loop ends immediately after receiving the file and ready to receive your sentences. In your code, the while loop read the first sentence, then checked remain_data > 0 effectively discarding sentence1

在修改后的while中,您只会在use_data >时调用recv()。recv()不被调用,如果剩下的数据== 0(懒惰的评估)。所以你的while循环在收到文件后立即结束,准备接收你的句子。在您的代码中,while循环读取第一个句子,然后检查残余数据>有效地丢弃了sentence1