Linux-C下C/S架构实例,实现文件传输功能
2016-11-09 10:25
676 查看
/*server_func.h*/ #ifndef SERVER_H #define SERVER_H #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<signal.h> #include<pthread.h> #include <errno.h> #define MAX_CON 10 #define MAX_SIZE 1024 #define CMD_EXIT "exit" #define CMD_DOWNLOAD_FILE "df" typedef enum tagCmdID { CMD_INVALID = -1, CMD_FILE_EXIST, CMD_FILE_NOT_EXIST }E_CMD_ID; typedef struct tagClientCom { E_CMD_ID cmd_id; long length; }T_CLIENT_COM_HEADER; typedef struct { int sfd; int cfd; char filename[128]; }tcp_info; int tcp_init(const char* ip, int port); int tcp_accept(int sfd); void * send_file(void * arg); void * pthread_recv(void *arg); void signalhandler(void); #endif
/*server_func.c*/ #include "server_func.h" int tcp_init(const char* ip, int port) //用于初始化 { int on = 1; int sfd = socket(AF_INET, SOCK_STREAM, 0); //首先建立一个Socket,向系统申请 if(sfd == -1) { printf("socket error: %s\n", strerror(errno)); return -1; } int ret = setsockopt( sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ); if(ret < 0) { printf("setsockopt error: %s", strerror(errno)); } struct sockaddr_in serveraddr; memset( &serveraddr, 0, sizeof(struct sockaddr) ); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(port); serveraddr.sin_addr.s_addr = INADDR_ANY; //或者INADDR_ANY if(bind(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr)) == -1) { printf("Bind error: %s\n", strerror(errno)); close(sfd); return -1; } if(listen(sfd, MAX_CON) == -1) //监听它 最大连接数为10 { printf("Listen error: %s\n", strerror(errno)); close(sfd); return -1; } return sfd; } int tcp_accept(int sfd) { struct sockaddr_in clientaddr; int addrlen = sizeof(struct sockaddr); int new_fd = accept(sfd, (struct sockaddr*)&clientaddr, &addrlen); memset(&clientaddr, 0, addrlen); if(new_fd == -1) { printf("accept error: %s\n", strerror(errno)); sleep(1); return -1; } printf("Client%d(%s %d) success connect...\n", new_fd, inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); return new_fd; } void * send_file(void * arg) { int needSend = sizeof(T_CLIENT_COM_HEADER); char *head = (char*)malloc(needSend); char buffer[MAX_SIZE]; T_CLIENT_COM_HEADER *com = (T_CLIENT_COM_HEADER*)malloc(sizeof(T_CLIENT_COM_HEADER)); tcp_info *client_info; client_info = ( tcp_info *)arg; com->length = needSend; memset(buffer, 0, sizeof(buffer)); if(access(client_info->filename, F_OK) >= 0) { FILE *fp = fopen(client_info->filename, "r"); fseek(fp, 0L, SEEK_END); long file_size = ftell(fp); rewind(fp); com->length += file_size; com->cmd_id = CMD_FILE_EXIST; memcpy(head, com, needSend); int sendlength = send(client_info->cfd, head, needSend, 0); printf("head->cmd_id = %d, head->length = %ld\n", com->cmd_id, com->length); do { int file_block_length = fread(buffer, sizeof(char), MAX_SIZE, fp); int len = send(client_info->cfd, buffer, file_block_length, 0); if(file_block_length <= 0) { break; } bzero(buffer, sizeof(buffer)); }while(1); fclose(fp); printf("File:\t%s \nTransfer Finished!\n", client_info->filename); } else { com->cmd_id = CMD_FILE_NOT_EXIST; memcpy(head, com, needSend); int sendlength = send(client_info->cfd, head, needSend, 0); } } void* pthread_recv(void *arg) { char buf[128] = {0}; tcp_info *client_info; client_info = ( tcp_info *)arg; memset(buf, 0, sizeof(buf)); while(1) { char commond[64]; char filename[128]; int ret = recv(client_info->cfd, buf, sizeof(buf), 0 ); if (ret < 0) { printf("receive error: %s\n", strerror(errno)); break; } else if(ret == 0) { printf("Client%d(Exception) exit!\n", client_info->cfd); break; } if(0 == strcmp(buf, CMD_EXIT)) { printf("Client%d exit!\n", client_info->cfd); break; } if((sscanf(buf, "%s %s", commond, filename) != 0) && (0 == strcmp(commond, CMD_DOWNLOAD_FILE))) { pthread_t pid; int ret; int length = 0; strcpy(client_info->filename, filename); ret = pthread_create(&pid, NULL, send_file, (void*)client_info); continue; } printf("Client%d: %s\n", client_info->cfd, buf); } close(client_info->cfd); free(client_info); pthread_exit(NULL); } void signalhandler(void) { sigset_t sigSet; sigemptyset(&sigSet); sigaddset(&sigSet,SIGINT); sigaddset(&sigSet,SIGQUIT); sigaddset(&sigSet,SIGPIPE); sigprocmask(SIG_BLOCK,&sigSet,NULL); }
/*server.c*/ #include "server_func.h" int main(int argc,char **argv) { int ret_send; int ret_recv; int sfd; int cfd; sfd = tcp_init("192.168.20.217", 1234); if(-1 == sfd) { return 0; } signalhandler(); do { pthread_t id2; tcp_info *info; cfd = tcp_accept(sfd); if(cfd < 0) { continue; } info = (tcp_info*)malloc(sizeof(tcp_info)); info->sfd = sfd; info->cfd = cfd; ret_recv = pthread_create(&id2, NULL, pthread_recv, (void*)info); if(ret_recv != 0) { printf("create pthread error!\n"); } }while(1); close(cfd); close(sfd); return 0; }
/*client_func.h*/ #ifndef CLIENT_H #define CLIENT_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <signal.h> #include <pthread.h> #include <errno.h> #include <libgen.h> #define MAX_SIZE 1024 #define CMD_EXIT "exit" #define CMD_DOWNLOAD_FILE "df" typedef enum tagCmdID { CMD_INVALID = -1, CMD_FILE_EXIST, CMD_FILE_NOT_EXIST }E_CMD_ID; typedef struct tagClientCom { E_CMD_ID cmd_id; long length; }T_CLIENT_COM_HEADER; typedef struct { int cfd; char filename[128]; }file_information; int tcp_connect(const char* ip, int port); void* recv_file(void *arg); void* pthread_send(void *arg); #endif
/*client_func.c*/ #include "client_func.h" int tcp_connect(const char* ip, int port) { int sfd = socket(AF_INET, SOCK_STREAM, 0); if(sfd == -1) { printf("socket error: %s", strerror(errno)); return -1; } struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(struct sockaddr) ); serveraddr.sin_family = AF_INET; serveraddr.sin_port = htons(port); serveraddr.sin_addr.s_addr = inet_addr(ip); if(connect(sfd, (struct sockaddr*) &serveraddr, sizeof(struct sockaddr)) == -1 ) { printf("connect error: %s", strerror(errno)); close(sfd); return -1; } return sfd; } void* recv_file(void *arg) { int needRecv = sizeof(T_CLIENT_COM_HEADER); int length = 0; long pos = 0; char *head = (char*)malloc(needRecv); char buffer[MAX_SIZE]; file_information *file_info; T_CLIENT_COM_HEADER *myNode = (T_CLIENT_COM_HEADER*)malloc(sizeof(T_CLIENT_COM_HEADER)); file_info = ( file_information *)arg; char *filename = basename(file_info->filename); memset(&buffer, 0, MAX_SIZE); while(pos < needRecv) { length = recv(file_info->cfd, head+pos, needRecv, 0); if (length < 0) { printf("Server Recieve Data Failed!\n"); break; } pos += length; } memcpy(myNode,head,needRecv); if(myNode->cmd_id == CMD_FILE_EXIST) { printf("File %s is sending...\n", filename); filename = NULL; FILE *fp = fopen(file_info->filename, "w"); length = 0; pos = 0; if (fp == NULL) { printf("File:\t%s Can Not Open To Write!\n", file_info->filename); return; } while(pos < myNode->length - needRecv) { int write_length; length = recv(file_info->cfd, buffer, MAX_SIZE, 0); if (length < 0) { printf("Recieve Data From Server Failed!\n"); break; } pos += length; write_length = fwrite(buffer, sizeof(char), length, fp); if (write_length < length) { printf("File:\t%s Write Failed!\n", file_info->filename); break; b5a6 } bzero(buffer, MAX_SIZE); } printf("Recieve File: %s\tFrom Server Finished!\n", file_info->filename); fclose(fp); } else if(myNode->cmd_id == CMD_FILE_NOT_EXIST) { printf("File %s is not exist!\n", file_info->filename); } free(head); free(myNode); } void* pthread_send(void *arg) { int *temp; char buf[128]; memset(buf, 0, sizeof(buf)); temp = (int *)arg; while(1) { char commond[64]; char filename[128]; char save_path[128]; int arg_cont; gets(buf); if(-1 == send(*temp, buf, sizeof(buf), 0)) { printf("send error: %s", strerror(errno)); close(*temp); return; } if(0 == strcmp(buf, CMD_EXIT)) { break; } if(((arg_cont = sscanf(buf, "%s %s %s", commond, filename, save_path)) != 0) && (0 == strcmp(commond, CMD_DOWNLOAD_FILE))) { if(arg_cont != 3) { printf("parameter error!\n"); continue; } file_information *file_info; pthread_t pid; int ret; file_info = (file_information *)malloc(sizeof(file_information)); memset(file_info, 0, sizeof(file_information)); strcpy(file_info->filename, save_path); file_info->cfd = *temp; ret = pthread_create(&pid, NULL, (void*)recv_file, (void*)file_info); if(ret != 0) { printf("create pthread error!\n"); } } } close(*temp); pthread_exit(NULL); }
/*client.c*/ #include "client_func.h" int main(int argc,char **argv) { int ret_send; pthread_t id1; int sfd = tcp_connect("192.168.20.217", 1234); int *p_sfd = &sfd; ret_send = pthread_create(&id1, NULL, (void*)pthread_send, (void*)p_sfd); if(ret_send != 0) { printf("create pthread error!\n"); } else { pthread_join(id1, NULL); } close(sfd); return 0; }
服务器端:
客户端1:
客户端2:
这是一个demo仅用来学习~
下面是传输文件运行截图,可以用来传输比较大的文件,试过传输3G多的文件:
后面加上makefile:
.PHONY : clean server
#server: client server.c
# gcc server.c -o server -lpthread
#client: client.c
# gcc client.c -o client -lpthread
#clean:
# pkill -9 server
# pkill -9 client
# rm server client
GCCTV = arm-linux-androideabi-gcc
GCC = gcc
object = server_func.o server.o client_func.o client.o
LFLAG = -lpthread
#LFLAG = -pie -fPIE
server : server.o server_func.o client
$(GCC) -o server server.o server_func.o $(LFLAG)
server.o : server.c
$(GCC) -c server.c $(LFLAG)
server_func.o : server_func.c
$(GCC) -c server_func.c $(LFLAG)
client : client.o client_func.o
$(GCC) -o client client.o client_func.o -lpthread
client.o : client.c
$(GCC) -c client.c -lpthread
client_func.o : client_func.c
$(GCC) -c client_func.c -lpthread
clean:
rm $(object)
相关文章推荐
- Linux C TCPSocket 传输文件简单实例-多线程实现
- OpenSSH实现Windows和Linux文件安全传输
- OpenSSH实现Windows和Linux文件安全传输
- Linux下使用socket传输文件的C语言简单实现
- 实现windows与linux之间的文件传输
- linux下实现ftp匿名用户的上传和下载文件功能
- query AjaxUpload实现多文件上传功能代码实例教程
- JAVA应用XFire框架来实现WebServie的大文件传输功能之一(下载)
- PHP+KINDEDIT+mysql+javascript实现文本编辑和文件上传功能实例
- LINUX下面PHP文件转换,DOC转PDF转SWF实现百度的文库预览功能
- 木马编程DIY第12篇之文件传输 2功能实现
- Linux下基于C实现的socket简单文件下载实例
- Linux下基于C实现的socket简单文件上传实例
- Jquery AjaxUpload实现文件上传功能代码实例教程
- Linux强大的IO重定向和管道功能(内含命令替换,实例:批量删除文件)
- JAVA应用XFire框架来实现WebServie的大文件传输功能之一(下载)
- php实现文件上传功能的详细代码实例
- 实现scp在linux或unix之间传输文件无需密码---如何配置scp文件传输
- 使用VMware自带的文件共享功能实现主机与虚拟机中的linux的文件共享
- Linux下基于C实现的socket简单文件下载实例 - 科技 - 紫苹果在线 - 快乐生活每一天