【发布时间】:2016-06-03 05:41:24
【问题描述】:
我正在尝试发送文件file_to_send.txt:
Lorem ipsum dolor sit amet,consectetur adipiscing elit。 Duis quam eros, fringilla et accumsan vitae, tincidunt scelerisque lacus。 Nulla facilisi。 Duis eget fringilla erat, sed dignissim libero。 Quisque nec velit auctor,varius ex id,mollis ipsum。 Suspendisse faucibus erat dolor,一种不正当的 dolor rutrum a。整数 sed tempus orci。 Quisque massa lacus、mollis quis efficitur infantum、viverra eu lorem。 Ut bibendum, velit id pharetra rutrum, ipsum quam rhoncus mauris, eleifend nulla mauris quis velit。
使用此代码:
客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#define PORT 16000
#define ADDRESS "localhost"
int main(int argc, char **argv)
{
int client_socket;
ssize_t len;
struct sockaddr_in remote_addr;
char buffer[BUFSIZ];
int file_size;
FILE *received_file;
int remain_data = 0;
char* destination_path = argv[1];
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
inet_pton(AF_INET, ADDRESS, &(remote_addr.sin_addr));
remote_addr.sin_port = htons(PORT);
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (connect(client_socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "Error on connect --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
recv(client_socket, buffer, BUFSIZ, 0);
file_size = atoi(buffer);
fprintf(stdout, "\nFile size : %d\n", file_size);
received_file = fopen(destination_path, "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(client_socket, buffer, BUFSIZ, 0) > 0) && (remain_data > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
fprintf(stdout, "Receive %d bytes and we hope :- %d bytes\n", static_cast<int>(len), remain_data);
}
fclose(received_file);
close(client_socket);
return 0;
}
服务器端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/sendfile.h>
using namespace std;
#define PORT 16000
#define ADDRESS "localhost"
int main(int argc, char **argv)
{
int server_socket;
int peer_socket;
socklen_t sock_len;
ssize_t len;
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
int fd;
int sent_bytes = 0;
char file_size[BUFSIZ];
struct stat file_stat;
off_t offset;
int remain_data;
char* file_to_serve = argv[1];
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1)
{
fprintf(stderr, "Error creating socket --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, ADDRESS, &(server_addr.sin_addr));
server_addr.sin_port = htons(PORT);
if ((bind(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) == -1)
{
fprintf(stderr, "Error on bind --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
if ((listen(server_socket, 5)) == -1)
{
fprintf(stderr, "Error on listen --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fd = open(file_to_serve, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
if (fstat(fd, &file_stat) < 0)
{
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n",static_cast<int>(file_stat.st_size));
sock_len = sizeof(struct sockaddr_in);
peer_socket = accept(server_socket, (struct sockaddr *)&peer_addr, &sock_len);
if (peer_socket == -1)
{
fprintf(stderr, "Error on accept --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Accept peer --> %s\n", inet_ntoa(peer_addr.sin_addr));
sprintf(file_size, "%d", static_cast<int>(file_stat.st_size));
len = send(peer_socket, file_size, sizeof(file_size), 0);
if (len < 0)
{
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Server sent %d bytes for the size\n", static_cast<int>(len));
offset = 0;
remain_data = file_stat.st_size;
while (((sent_bytes = sendfile(peer_socket, fd, &offset, BUFSIZ)) > 0) && (remain_data > 0))
{
fprintf(stdout, "Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, static_cast<int>(offset), static_cast<int>(remain_data));
remain_data -= sent_bytes;
fprintf(stdout, "Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, static_cast<int>(offset), static_cast<int>(remain_data));
}
close(peer_socket);
close(server_socket);
return 0;
}
从终端运行代码:
服务器端:
// compile
$ g++ server.cpp -o server_side
// run client
$ ./server_side "$HOME/file_to_send.txt"
客户端:
// compile
$ g++ client.cpp -o client_side
// run client
$ ./client_side "$HOME/received_file.txt"
我没有收到所有文件。 有人可以测试此代码并帮助我解决问题吗?
谢谢。
【问题讨论】:
-
"有人可以测试这段代码并帮助我解决问题吗?" you 调试代码并解决问题怎么样?如果您已经尝试过调试,请与我们分享您发现的内容以及无法继续进行的原因。
-
当我将
fwrite(buffer, sizeof(char), len, received_file);中的变量len更改为等于8192 的BUFSIZ 时,我收到了所有文件和一些随机字符:^@^@^@^@^@^ @^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^ -
不要让我们从头开始调试这是重点。您的代码中显然有一些调试语句。至少显示这些调试的输出并准确告诉我们结果是什么(输出中缺少一个单词?预期输出的一半?没有输出?等等)。
-
@EJP 你能解释一下 C++ 问题如何与使用不同 API 的 java 问题和 java 答案重复吗?好的,它是套接字,好的,它肯定是另一个问题的副本,但至少提供一个足够接近这个问题的 C++ !
标签: c++ linux sockets client-server