c语言 TCP文件传输协议代码
时间: 2023-08-02 11:07:22 浏览: 89
下面是一个简单的 TCP 文件传输协议的 C 语言代码示例:
服务端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#define SERVER_PORT 8888
#define BUF_SIZE 1024
int main() {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len;
char buf[BUF_SIZE];
FILE *fp;
size_t file_size, read_size, total_size = 0;
// 创建 socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT);
// 绑定 socket
if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
perror("bind");
exit(1);
}
// 监听 socket
if (listen(server_fd, 5) < 0) {
perror("listen");
exit(1);
}
printf("Listening on port %d...\n", SERVER_PORT);
// 接受客户端连接
client_addr_len = sizeof(client_addr);
if ((client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_len)) < 0) {
perror("accept");
exit(1);
}
printf("Client connected: %s\n", inet_ntoa(client_addr.sin_addr));
// 接收文件名
memset(buf, 0, sizeof(buf));
if (recv(client_fd, buf, BUF_SIZE, 0) < 0) {
perror("recv");
exit(1);
}
printf("Received file name: %s\n", buf);
// 打开文件
if ((fp = fopen(buf, "rb")) == NULL) {
perror("fopen");
exit(1);
}
// 发送文件大小
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
if (send(client_fd, &file_size, sizeof(file_size), 0) < 0) {
perror("send");
exit(1);
}
// 发送文件内容
while ((read_size = fread(buf, 1, BUF_SIZE, fp)) > 0) {
if (send(client_fd, buf, read_size, 0) < 0) {
perror("send");
exit(1);
}
total_size += read_size;
printf("Sent %ld bytes.\n", total_size);
}
printf("File sent: %s (%ld bytes)\n", buf, total_size);
// 关闭文件和 socket
fclose(fp);
close(client_fd);
close(server_fd);
return 0;
}
```
客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#define SERVER_PORT 8888
#define SERVER_IP "127.0.0.1"
#define BUF_SIZE 1024
int main() {
int sock_fd;
struct sockaddr_in server_addr;
char buf[BUF_SIZE];
FILE *fp;
size_t file_size, read_size, total_size = 0;
// 创建 socket
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
perror("inet_pton");
exit(1);
}
// 连接服务器
if (connect(sock_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
perror("connect");
exit(1);
}
// 发送文件名
strcpy(buf, "test.txt");
if (send(sock_fd, buf, strlen(buf), 0) < 0) {
perror("send");
exit(1);
}
// 接收文件大小
if (recv(sock_fd, &file_size, sizeof(file_size), 0) < 0) {
perror("recv");
exit(1);
}
printf("File size: %ld bytes.\n", file_size);
// 打开文件
if ((fp = fopen(buf, "wb")) == NULL) {
perror("fopen");
exit(1);
}
// 接收文件内容
while (total_size < file_size) {
read_size = file_size - total_size > BUF_SIZE ? BUF_SIZE : file_size - total_size;
if (recv(sock_fd, buf, read_size, 0) < 0) {
perror("recv");
exit(1);
}
fwrite(buf, 1, read_size, fp);
total_size += read_size;
printf("Received %ld bytes.\n", total_size);
}
printf("File received: %s (%ld bytes)\n", buf, total_size);
// 关闭文件和 socket
fclose(fp);
close(sock_fd);
return 0;
}
```
这个示例中,服务端和客户端使用了简单的文件名字符串来传输文件名,实际上可以使用更加严谨的协议来传输文件名和文件大小等信息。另外,示例中没有考虑文件传输过程中出现错误的处理情况,实际应用中需要加入更加完善的错误处理。