乐闻世界logo
搜索文章和话题

Send and Receive a file in socket programming in Linux with C/ C ++ ( GCC / G ++)

5 个月前提问
4 个月前修改
浏览次数48

4个答案

1
2
3
4

在 Linux 系统中使用 C/C++ 进行套接字编程,可以使用 TCP 或 UDP 协议来发送和接收文件。下面我将通过一个简单的例子来说明如何使用 TCP 协议(因为其提供了面向连接的稳定数据传输)进行文件传送。

1. 服务器端程序

服务器端的基本任务是监听一个端口,接受客户端的连接,然后读取客户端发送的文件数据,并将其写入本地存储。下面是一个简单的服务器端示例代码:

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; char *filename = "received_file.txt"; // 创建 socket 文件描述符 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 绑定 socket 到 localhost 的 8080 端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听这个端口 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); } // 读取数据并写入文件 FILE *file = fopen(filename, "wb"); int bytes_read; while ((bytes_read = read(new_socket, buffer, BUFFER_SIZE)) > 0) { fwrite(buffer, 1, bytes_read, file); } fclose(file); close(new_socket); close(server_fd); return 0; }

2. 客户端程序

客户端的任务是连接到服务器,读取本地文件数据,并将数据发送到服务器。下面是对应的客户端示例代码:

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/types.h> #define PORT 8080 #define BUFFER_SIZE 1024 int main() { int sock = 0; struct sockaddr_in serv_addr; char *filename = "file_to_send.txt"; char buffer[BUFFER_SIZE] = {0}; // 创建 socket 文件描述符 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将 IPv4 地址从文本转换为二进制形式 if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // 连接到服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } // 读取并发送文件内容 FILE *file = fopen(filename, "rb"); int bytes_read; while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file)) > 0) { write(sock, buffer, bytes_read); } fclose(file); close(sock); return 0; }

解释

  • 服务器端 使用 socket(), bind(), listen(), 和 accept() 函数来设置 TCP 服务器,接受客户端的连接。
  • 客户端 使用 socket()connect() 函数创建一个到服务器的连接。
  • 文件数据以二进制形式通过套接字传输。
  • 使用 read()write() 函数在套接字和文件之间传输数据。

这只是一个基本示例,实际应用中可能需要处理错误、增加安全性或改进性能。

2024年6月29日 12:07 回复

在 Linux 下使用 C/C++ 进行套接字编程涉及到使用 POSIX 套接字 API。在本例中,我们将通过简单的 TCP 连接来介绍如何发送和接收文件。这里将分为两部分:服务器端和客户端。

1. 服务器端

服务器端的任务是监听来自客户端的连接,接收文件,并将其保存到磁盘上。

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #define PORT 8080 #define BUFFER_SIZE 4096 int main() { int server_fd, new_socket; struct sockaddr_in address; int addr_len = sizeof(address); char buffer[BUFFER_SIZE] = {0}; FILE *file_ptr; // 创建套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 定义套接字类型 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听套接字 if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // 接受来自客户端的连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addr_len)) < 0) { perror("accept"); exit(EXIT_FAILURE); } // 打开文件以写入 file_ptr = fopen("received_file", "wb"); if (file_ptr == NULL) { perror("Failed to open file"); exit(EXIT_FAILURE); } // 从套接字读取数据并写入文件 int bytes_read; while ((bytes_read = recv(new_socket, buffer, BUFFER_SIZE, 0)) > 0) { fwrite(buffer, 1, bytes_read, file_ptr); } // 关闭文件 fclose(file_ptr); // 关闭套接字 close(new_socket); close(server_fd); return 0; }

2. 客户端

客户端的任务是连接到服务器,读取文件并发送数据。

c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #define SERVER_IP "127.0.0.1" #define PORT 8080 #define BUFFER_SIZE 4096 int main() { int sock = 0; struct sockaddr_in serv_addr; char buffer[BUFFER_SIZE] = {0}; FILE *file_ptr; // 创建套接字 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket creation error"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将 IP 地址从字符串转换为二进制 if(inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { perror("Invalid address/ Address not supported"); exit(EXIT_FAILURE); } // 连接到服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("Connection Failed"); exit(EXIT_FAILURE); } // 打开文件以读取 file_ptr = fopen("file_to_send", "rb"); if (file_ptr == NULL) { perror("Failed to open file"); exit(EXIT_FAILURE); } // 读取文件并发送数据 int bytes_read; while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, file_ptr)) > 0) { send(sock, buffer, bytes_read, 0); } // 关闭文件 fclose(file_ptr); // 关闭套接字 close(sock); return 0; }

总结

上述代码展示了在 Linux 中使用 C/C++ 进行基本的文件传输。服务器端设置套接字,接受连接,并接收数据将其保存到文件中。客户端连接到服务器,读取本地文件并将数据发送到服务器。这是一个基础示例,实际应用中可能需要处理错误情况、增加安全性措施等。

2024年6月29日 12:07 回复

在使用 C/C++ (GCC/G++) 在 Linux 环境下进行套接字编程以发送和接收文件时,基本步骤主要包括建立连接、发送文件信息、发送文件数据、以及关闭连接。以下是一个简单的示例,展示了如何实现这些步骤。

1. 创建套接字

首先,我们需要在发送端和接收端各自创建一个套接字。套接字是实现网络通信的基础。

c
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int sockfd; struct sockaddr_in servaddr; // 创建套接字 sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 设置服务器地址 servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 连接服务器 if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("connect failed"); exit(EXIT_FAILURE); }

2. 发送文件信息

在发送文件内容之前,通常需要先发送一些文件信息,如文件大小或文件名,以便接收端做好相应的准备。

c
#include <stdio.h> #include <stdlib.h> void send_file_info(int sockfd, const char* filename) { char buffer[1024]; FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("File opening failed"); return; } // 获取文件大小 fseek(file, 0L, SEEK_END); long filesize = ftell(file); rewind(file); // 发送文件大小 sprintf(buffer, "%ld", filesize); send(sockfd, buffer, sizeof(buffer), 0); }

3. 发送文件数据

文件信息发送完毕后,接下来就是发送文件的数据。

c
void send_file_data(int sockfd, const char* filename) { char buffer[1024]; FILE *file = fopen(filename, "rb"); if (file == NULL) { perror("File opening failed"); return; } int bytes_read; while ((bytes_read = fread(buffer, 1, sizeof(buffer), file)) > 0) { send(sockfd, buffer, bytes_read, 0); } fclose(file); }

4. 接收文件

在接收端,我们需要根据发送端发来的文件信息来接收文件数据。

c
void receive_file(int sockfd, const char* out_filename) { char buffer[1024]; FILE *file = fopen(out_filename, "wb"); if (file == NULL) { perror("File opening failed"); return; } int bytes_received; while ((bytes_received = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) { fwrite(buffer, 1, bytes_received, file); } fclose(file); }

5. 关闭套接字

数据传输完成后,不要忘记关闭套接字。

c
close(sockfd);

注意事项

  • 确保错误处理充分,比如在网络操作失败时进行适当的清理。
  • 考虑到网络延迟和中断,确保实现可以处理部分读写的情况。
  • 安全性也是重要考虑因素,尤其是在传输敏感数据时。

以上就是用 C/C++ 在 Linux 下进行文件传输的基本框架和示例代码。

2024年6月29日 12:07 回复

在 Linux 系统中,使用 C/C++ 进行套接字编程是处理网络通信的一种常见方法。在套接字编程中,发送和接收文件涉及到创建套接字、连接到服务器、读取文件内容以及通过网络发送数据等步骤。接下来,我将详细介绍在 Linux 中使用 C/C++ (GCC/G++) 实现文件传输的主要步骤,并提供代码示例。

1. 创建套接字

首先,需要创建一个套接字来进行网络通信。我们通常使用 socket() 函数来创建套接字。

c
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int sockfd; struct sockaddr_in servaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket creation failed"); exit(EXIT_FAILURE); } // 设置服务器地址 servaddr.sin_family = AF_INET; servaddr.sin_port = htons(12345); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

2. 连接到服务器

创建套接字后,使用 connect() 函数连接到服务器。

c
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) { perror("connection with the server failed"); exit(EXIT_FAILURE); }

3. 读取和发送文件

连接到服务器后,可以开始读取本地文件并通过套接字发送。

c
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int fd; ssize_t read_bytes, sent_bytes; char buffer[1024]; fd = open("example.txt", O_RDONLY); if (fd < 0) { perror("failed to open file"); close(sockfd); exit(EXIT_FAILURE); } while ((read_bytes = read(fd, buffer, sizeof(buffer))) > 0) { sent_bytes = send(sockfd, buffer, read_bytes, 0); if (sent_bytes < 0) { perror("failed to send file"); close(fd); close(sockfd); exit(EXIT_FAILURE); } } close(fd);

4. 接收文件

服务器端的代码类似,不过使用 recv() 函数来接收数据,并将接收的数据写入文件。

c
ssize_t recv_bytes, write_bytes; int fd = open("received.txt", O_WRONLY | O_CREAT, 0666); if (fd < 0) { perror("failed to open file for writing"); exit(EXIT_FAILURE); } while ((recv_bytes = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) { write_bytes = write(fd, buffer, recv_bytes); if (write_bytes < 0) { perror("failed to write to file"); close(sockfd); close(fd); exit(EXIT_FAILURE); } } close(fd);

5. 关闭套接字和清理资源

在文件传输完成后,关闭套接字和文件描述符,释放任何占用的资源。

c
close(sockfd);

这就是使用 C/C++ 在 Linux 环境下进行文件的发送和接收的基本过程。通过适当地管理错误处理和资源释放,可以确保程序的健壮性和效率。

2024年6月29日 12:07 回复

你的答案