【发布时间】:2017-12-11 21:41:50
【问题描述】:
我想在单个客户端服务器连接上发送多个文件。服务器应该接受来自客户端的连接,然后遍历一个文件夹并将其中的每个文件发送给客户端。有什么好的方法可以做到这一点,以便客户端在收到每个文件后可以保存它们,然后正确读取下一个文件。
我有以下服务器代码,它只发送 1 个文件并关闭。
/*
Server side C/C++ program to demonstrate Socket programming
compile:
gcc serverFile.c -o serverFile
run:
./serverFile
from http://www.geeksforgeeks.org/socket-programming-cc/
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
char *file_path = "image.jpg";
int input_file;
input_file = open(file_path, O_RDONLY);
if (input_file == -1) {
exit(EXIT_FAILURE);
}
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char *hello = "Hello from server";
// Creating socket file descriptor. AF_INET is IPv4, SOCK_STREAM is tcp.
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
//Set socket option (optional?). SOL_SOCKET is socket level argument.
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( PORT );
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
// If you want to read multiple server connections.
//int x;
//for (x = 0; x < 3; x++){
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t*)&addrlen))<0)
{
perror("accept");
exit(EXIT_FAILURE);
}
valread = read( new_socket , buffer, 1024);
printf("%s\n",buffer );
/*********************** read file and send it over socket ****************************/
//unsigned char buffer[1000];
while (1) {
// Read data into buffer. We may not have enough to fill up buffer, so we
// store how many bytes were actually read in bytes_read.
int bytes_read = read(input_file, buffer, sizeof(buffer));
if (bytes_read == 0) // We're done reading from the file
break;
if (bytes_read < 0) {
// handle errors
printf("read error!\n");
}
// You need a loop for the write, because not all of the data may be written
// in one call; write will return how many bytes were written. p keeps
// track of where in the buffer we are, while we decrement bytes_read
// to keep track of how many bytes are left to write.
void *p = buffer;
while (bytes_read > 0) {
int bytes_written = write(new_socket, p, bytes_read);
if (bytes_written <= 0) {
// handle errors
}
bytes_read -= bytes_written;
p += bytes_written;
}
}
/***************************************************************************************/
//send(new_socket , hello , strlen(hello) , 0 );
//printf("Hello message sent\n");
close(new_socket);
close(server_fd);
//}
return 0;
}
【问题讨论】:
-
问题是什么?
-
您需要定义一个通信协议来定义文件何时开始和结束,以便客户端可以区分两个文件。这可能就像在发送文件之前发送文件的大小一样简单。
-
@JakeFreeman 如何编写服务器代码以在 1 个连接中发送多个文件?
-
@user4581301 你有示例代码吗?
-
这是某种锻炼/学校作业,还是您需要实际的解决方案?我问是因为当您考虑生产应用程序时设计会发生变化,主要是由于错误处理、故障恢复等......?对于现实世界的应用程序,我强烈建议使用现有协议(HTTP / FTP 等),这将有助于根据需要创建不同的客户端。
标签: c sockets client-server