当前位置:网站首页>简易网络文件拷贝的C实现
简易网络文件拷贝的C实现
2022-07-31 04:19:00 【蓝牙先生】
效果
服务端
./s
客户端读服务端文件
./c 127.0.0.1 src_file dst_file 0
客户端写文件到服务端
./c 127.0.0.1 src_file dst_file 1
服务端实现server.c
#include <stdio.h> #include <stdbool.h> #include <sys/types.h> #include <sys/socket.h> #include <stdint.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "cs.c" int init_socket(void) { int opt = 1; struct sockaddr_in servaddr = {0}; unsigned int len = sizeof(opt); int sock = socket(AF_INET, SOCK_STREAM, 0); bool ok = false; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERVICE_PORT); do { if(sock >= 0) { /* null */ } else { perror("socket"); break; } if(!setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, len)) { /* null */ } else { perror("setsockopt"); break; } if (!bind(sock, (struct sockaddr *)&servaddr,sizeof(servaddr))) { /* null */ } else { perror("bind"); break; } if (listen(sock, 1) == 0) { /* null */ } else { perror("listen"); break; } ok = true; } while(0); if(ok) { /* null */ } else if(sock >= 0) { close(sock); } return ok ? sock : -1; } int main(int argc, char *argv[]) { int client = -1; int socklen = sizeof(struct sockaddr_in); struct sockaddr_in clientaddr = {0}; int sock = init_socket(); while(sock >= 0) { client = accept(sock,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen); if(client > 0) { printf("detect client\n"); } else { perror("accept"); continue; } op.magic = 0; if (recv(client, &op,sizeof(op), 0) == sizeof(op)) { /* null */ } else { printf("recv op err\n"); } if(op.magic != START_EXIT) { printf("op.magic != START_EXIT\n"); } else { switch(op.read_write) { case 0: printf("client read file:%s -> %s\n", op.src_file, op.dst_file); client_read_file(client, (char *)op.src_file); break; case 1: printf("client write file:%s -> %s\n", op.src_file, op.dst_file); client_write_file(client, (char *)op.dst_file); break; default: break; } } close(client); } return 0; } void client_read_file(int client, char *filename) { // server read to -> client __read(client, filename); } void client_write_file(int client, char *filename) { // client send to -> server __write(client, filename); }
客户端实现client.c
#include <stdio.h> #include <stdbool.h> #include <sys/types.h> #include <sys/socket.h> #include <stdint.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "cs.c" int init_socket(int argc, char *argv[]) { int sock = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; unsigned int len = sizeof(opt); struct sockaddr_in servaddr = {0}; bool ok = false; servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = inet_addr(argv[1]); servaddr.sin_port = htons(SERVICE_PORT); do { if(sock >= 0) { /* null */ } else { perror("socket"); break; } if(!setsockopt(sock , SOL_SOCKET, SO_REUSEADDR, &opt, len)) { /* null */ } else { perror("setsockopt"); break; } if(!connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr))) { /* null */ } else { perror("connect"); break; } ok = true; } while(0); if(ok) { /* null */ } else if(sock >= 0){ close(sock); } return ok ? sock : -1; } int main(int argc, char *argv[]) { int sock = init_socket(argc, argv); memcpy(op.src_file, argv[2], strlen(argv[2])); memcpy(op.dst_file, argv[3], strlen(argv[2])); op.read_write = atoi(argv[4]); op.magic = START_EXIT; if(send(sock, &op, sizeof(op), 0) != sizeof(op)) { perror("send"); } else { switch(op.read_write) { case 0: printf("client read file:%s -> %s\n", op.src_file, op.dst_file); client_read_file(sock, (char *)op.dst_file); break; case 1: printf("client write file:%s -> %s\n", op.src_file, op.dst_file); client_write_file(sock, (char *)op.src_file); break; default: break; } close(sock); } return 0; } void client_read_file(int client, char *filename) { // server send to -> client __write(client, filename); } void client_write_file(int client, char *filename) { // client send to -> server __read(client, filename); }
文件读写实现cs.c
#define READ_WRITE_END 0xBB #define START_EXIT 0xCC #define SERVICE_PORT 1234 struct trans_op { uint8_t magic; uint8_t read_write;//0:read 1:write uint32_t size; uint8_t src_file[64]; uint8_t dst_file[64]; uint8_t buffer[512 - 8 - 128]; }; static struct trans_op op; void client_read_file(int client, char *filename); void client_write_file(int client, char *filename); void __write (int client, char *filename) { int fd = open(filename, O_CREAT | O_WRONLY, 0777); ssize_t res = 0; ssize_t total = 0; printf("write %s\n", filename); if(fd < 0) { perror("open"); } else { while(1) { memset(&op, 0, sizeof(op)); if((res = recv(client, &op, sizeof(op), 0)) != sizeof(op)) { perror("recv error"); break; } else if(op.magic == READ_WRITE_END) { printf("magic is bb exit.\n"); break; } else if(write(fd, op.buffer, op.size) == -1) { perror("write"); break; } else { total += op.size; } } printf("toatl = %ld\n", total); close(fd); } /* check return code */ if(op.magic != READ_WRITE_END || op.size != total) { printf("end fail\n"); } else { printf("end success\n"); } /* replay */ op.magic = START_EXIT; op.size = total; send(client, &op, sizeof(op), 0); } void __read(int client, char *filename) { int fd = open(filename, O_RDONLY, 0777); ssize_t total = 0; printf("read %s\n", filename); if(fd < 0) { perror("open"); } else { while(1) { memset(&op, 0, sizeof(op)); if((op.size = read(fd, op.buffer, sizeof(op.buffer))) <= 0 ) { perror("read end or error"); break; } else if(send(client, &op, sizeof(op),0) != sizeof(op)) { perror("send error"); break; } else { total += op.size; } } /* relply */ op.magic = READ_WRITE_END; op.size = total; if(send(client, &op, sizeof(op), 0) == sizeof(op)) { /* null */ } else { perror("send error"); } printf("toatl = %ld\n", total); close(fd); } /* check return code */ recv(client, &op, sizeof(op), 0); if(op.magic != START_EXIT || op.size != total) { printf("end fail, op.magic,op.size=%d,%d\n", op.magic, op.size); } else { printf("end success\n"); } }
<完>
边栏推荐
- Just debuted "Fight to Fame", safety and comfort are not lost
- Musk talks to the "virtual version" of Musk, how far is the brain-computer interaction technology from us
- MySQL数据库安装配置保姆级教程(以8.0.29为例)有手就行
- (六)枚举、注解
- Safety 20220715
- Error EPERM operation not permitted, mkdir ‘Dsoftwarenodejsnode_cache_cacach两种解决办法
- Postgresql 15 source code analysis (5) - pg_control
- MySQL数据库必会的增删查改操作(CRUD)
- [C language] General method of expression evaluation
- [C language] General method for finding the sum of the greatest common factor and the least common multiple of two integers m and n, the classical solution
猜你喜欢
BUG消灭者!!实用调试技巧超全整理
重磅 | 开放原子校源行活动正式启动
Learning DAVID Database (1)
产学研用 共建开源人才生态 | 2022开放原子全球开源峰会教育分论坛圆满召开
The BP neural network
MySQL数据库备份
已解决(最新版selenium框架元素定位报错)NameError: name ‘By‘ is not defined
行业落地呈现新进展 | 2022开放原子全球开源峰会OpenAtom OpenHarmony分论坛圆满召开
How Zotero removes auto-generated tags
「 每日一练,快乐水题 」1331. 数组序号转换
随机推荐
三子棋的代码实现
Redis 使用 sorted set 做最新评论缓存
"A daily practice, happy water problem" 1331. Array serial number conversion
qlib架构
数字经济时代的开源数据库创新 | 2022开放原子全球开源峰会数据库分论坛圆满召开
MySQL数据库安装配置保姆级教程(以8.0.29为例)有手就行
(8) Math class, Arrays class, System class, Biglnteger and BigDecimal classes, date class
「 每日一练,快乐水题 」1331. 数组序号转换
MySQL数据库增删改查(基础操作命令详解)
open failed: EACCES (Permission denied)
扫雷游戏(c语言写)
ERROR 1064 (42000) You have an error in your SQL syntax; check the manual that corresponds to your
VScode+ESP32 quickly install ESP-IDF plugin
[C language] General method of base conversion
MATLAB/Simulink & & STM32CubeMX tool chain completes model-based design development (MBD) (three)
Exsl file preview, word file preview web page method
MySQL based operations
Vue项目通过node连接MySQL数据库并实现增删改查操作
Bubble sort, selection sort, insertion sort, binary search directly
The application and practice of mid-to-platform brand advertising platform