【发布时间】:2018-01-21 09:11:55
【问题描述】:
我编写了程序,它运行良好,但我想使用 sendfile() 重写它,现在我陷入了一个循环。
服务器端:
- 发送姓名 = ok
- 发送 md5 校验和 = ok
- 发送大小 = ok
- 发送文件 = ko
客户端:
- recv 名称 = 好的
- recv md5 cecksum = ok
- recv 大小 = ok
- 创建目录并创建文件 = ok
- 将数据写入创建的文件 = ko
P.S 在以前版本的程序中,我坚持了一段时间,但这取决于我使用 printf 的程度,为什么?例如,我添加一行 printf 程序卡住,删除它,工作正常。
UPDT:重写代码客户端/服务器
客户
/* Received file name */
int rc_byte = 0;
rc_byte = recv(fd, rx_tx_file->out_name, sizeof(rx_tx_file->out_name),0);
if (rc_byte < 0){
perror("Failed to receive file name: ");
exit(-1);
} else
printf("Recv out name %s\n", rx_tx_file->out_name);
//printf("file name rc %s\n", rx_tx_file->out_name);
trimm_path_name(rx_tx_file);
/* Received md5sum */
rc_byte = recv(fd, rx_tx_file->md5sum, sizeof(rx_tx_file->md5sum), 0);
if (rc_byte < 0) {
perror("Failed to receive check sum: ");
exit(-1);
} else
printf("recv md5s %s\n", rx_tx_file->md5sum);
/* Received file size */
rc_byte = recv(fd, &size, sizeof(size), 0);
if(rc_byte < 0) {
perror("Recevid size of file: ");
exit(-1);
}
printf("%d recv size\n", size);
to_read = size;
if (stat(dir, &st) == -1){
mkdir(dir, 0777);
}
send_data:(添加函数到服务器)
void send_data(int client_fd, m_file *rx_tx_file, int option, int size) {
int send_byte = 0;
int total_send = 0;
if (option == SEND_NAME) {
while (total_send < strlen(rx_tx_file->in_name)) {
send_byte = send(client_fd, rx_tx_file->in_name, sizeof(rx_tx_file->in_name),0);
if(send_byte == -1) {
perror("Failed to send file name to client: ");
exit(SEND_TO_CLIENT_ERROR);
}
total_send += send_byte;
}
}
else if (option == SEND_MD5) {
total_send = 0;
send_byte = 0;
while (total_send < strlen(rx_tx_file->md5sum)) {
send_byte = send(client_fd, rx_tx_file->md5sum, sizeof(rx_tx_file->md5sum),0);
if(send_byte == -1){
perror("Failed to send file md5sum to client: ");
exit(-1);
}
total_send += send_byte;
}
}
else if (option == SEND_SIZE) {
send_byte = send(client_fd, &size, sizeof(size),0);
if (send_byte == -1) {
perror("Failed to send size: ");
}
}
}
服务器:
client_fd = accept(server_fd, (struct sockaddr*) &client_addr, &length)
/*send name of file*/
send_data(client_fd, rx_tx_file, SEND_NAME, 0);
/*send md5 sum*/
take_check_sum(rx_tx_file,rx_tx_file->file_in, 0);
send_data(client_fd, rx_tx_file, SEND_MD5, 0);
/*send size of file*/
size = stats.st_size;
send_data(client_fd, rx_tx_file, SEND_SIZE, size);
remain_data = stats.st_size;
printf("File [%s] ready to send\ncheck sum [%s]\n", rx_tx_file->in_name,rx_tx_file->md5sum);
while (((send_byte = sendfile(client_fd, file_fd, &offset, size)) > 0) && (remain_data > 0))
{
remain_data -= send_byte;
printf("remain %d", remain_data);
}
printf("Succesfully");
由于我使用一个客户端并传递应该通过命令行参数在服务器端发送的文件,我不需要等待 (client_fd = accpet) 我只使用一个连接并关闭服务器。现在它的工作很好。但是一个问题是开放的,我应该如何重写客户端以循环接收数据。我不知道我应该接收哪个大小,因此我无法将正确的条件写入我的 while 循环。感谢大家的帮助。
【问题讨论】:
-
这里
buffer = malloc(size); while (((len = recv(fd, buffer, sizeof(buffer), ...操作员sizeof不符合您的预期。它返回指针的大小(4 或 8)。它不返回size。 -
您还希望客户端在
rev()也返回0时立即中止操作。正如这告诉客户端,服务器关闭了连接。客户端将无法再通过当前套接字描述符接收任何内容。 -
为了传输文件名,代码发送
strlen(rx_tx_file->in_name)+1字节并接收sizeof(rx_tx_file->out_name)字节,这很可能是不同的,然后是发送的数字。 -
我更新了一些问题,关于它应该如何在一段时间内从服务器接收数据,它似乎如果我开始在客户端循环接收数据,发生类似不匹配的事情,在服务器一个循环中更快比另一个,在客户端我在同一个循环中启动文件的recv名称和md5总和,当我传递到下一个时,所有日期都是前一个循环中的recv并且它卡住了。
-
关于如何通过 TCP 套接字接收/读取 n 字节请查看我在类似问题上给出的答案:stackoverflow.com/a/20149925/694576
标签: c sockets tcp tcp-ip sendfile