linux网络编程之实现跨平台PC之间进行文件传输
来源:互联网 发布:dsm数据 编辑:程序博客网 时间:2024/06/06 19:21
//实现两台计算机进行文件传输,包括跨平台传输即linux与windows之间
//TCP的文件传输
//文件大小不限制,需要做到将大文件分包去做
server.c
//服务端程序int main(int arg,char * args[ ]){if(arg < 2){printf("scanf parameter failed\n");return 0;}int port = itoi(args[1]);if(port == 0){printf("port %d is invalid\n ",port);return 0;}printf("receive begin\n");if(recv_work(port) == 1)printf("receive success\n");elseprintf("receive failed\n");return 0;}
client.c
//实现两台计算机进行文件传输,包括跨平台传输即linux与windows之间//TCP的文件传输//文件大小不限制,需要做到将大文件分包去做//编译时传入的参数是包括:服务器IP地址、端口号、传送的文件名//client端int main(int arg,char * args[ ]){//先是判断传入的参数个数if(arg < 4){printf("scanf parameter failed\n");return 0;}//判断端口号int port = atoi(args[2]);if(port == 0){printf("port %d is invalid\n ",port);return 0;}printf("%s send begin\n",args[3]);//将调用一个send_work函数传入服务器IP地址、端口号、传送的文件名if(send_work(args[1],port,args[3]) == 1){sleep(3);printf("%s send success\n",args[3]);}else{printf("%s send failed\n",args[3]);}return EXIT_SUCCESS;}
pub.h
#ifndef PUB_H_#define PUB_H_int send_work(const char * hostname,int port,const char * filename);int recv_work(int port);#endif /* PUB_H_ */
pub.c
#include <stdlib.h>#include <unistd.h>#include <sys/socket.h>#include <arpa/inet.h>#include <errno.h>#include <string.h>#define SOCKET int#endif#include <stdio.h>#include "pub.h"#define BUFSIZE 262144 //1024 * 256//为什么要定义一个宏,解释一下,因为此程序可以保证在linux与windows系统下均可运行。//#ifdef WIN//#include <WinSock2.h>//#else 为什么这样写呢,在windows下socket被封装在此头文件下,而且套接口的类型为SOCKET,而linux下的套接口为int型,故作此标记int init_socket(){//如果是windows系统,执行如下代码,linux系统直接略过此代码#ifdef WINWORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(1, 1);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return -1;}if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){ WSACleanup(); return -1;}#endifreturn 0;}SOCKET socket_connect(const char * hostname,int port)//连接IP地址和port端口号{if(init_socket() == -1)//因为linux与windows系统下使用socket有区别,windows下必须使用此函数初始化(同样用到宏)return 0;SOCKET st = socket(AF_INET,SOCK_STREAM,0);if(st == 0)return 0;struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(hostname);if(connect(st,(struct sockaddr *) &addr,sizeof(addr)) == -1){printf("connect to %s:%d failed %s\n", hostname, port, strerror(errno));return 0; // 连接失败,返回0}else{return st;}}void getfilename(const char * filename, char * name){int len = strlen(filename);int i;for(i = (len -1);i >= 0;i--){if((filename[i] == '\\') ||(filename[i] == '/')){break;}}strcpy(name,&filename[i + 1]);}//连接到hostname指定的IP地址和port端口号int send_work(const char * hostname,int port,const char * filename){SOCKET st = socket_connect(hostname,port);if(st == 0)return 0;//连接成功后,需要将传送的文件打开FILE * fd = fopen(filename,"rb");if(fd == NULL)//判断文件描述符,看文件是否打开{printf("open %s failed\n",filename);return 0;}char *buf = malloc(BUFSIZE) ;//申请一个缓冲区,将文件数据放置在此memset(buf,0,BUFSIZE);//将完整的文件名解析出来getfilename(filename,buf);//将解析出来的文件名先发送给服务端,等待服务端接收,若接收成功并返回一个信号给客户端int rc = send(st,buf,strlen(buf),0);if(rc <= 0)//在判断一下是否成功发出{if(rc < 0)printf("send failed %s\n", strerror(errno));elseprintf("socket disconnect\n");}else{memset(buf,0,sizeof(buf));//等待服务器端传来的消息if(recv(st,buf,BUFSIZE,0) <= 0){printf("socket disconnect\n");}else{if(strncmp(buf,"OK",2) == 0){while(1){memset(buf,0,BUFSIZE);rc = fread(buf,1,BUFSIZE,fd);if(rc <= 0){if (rc < 0) printf("fread failed %s\n", strerror(errno));break;}else{rc = send(st,buf,rc,0);if(rc <= 0){if (rc < 0) printf("fread failed %s\n", strerror(errno));elseprintf("socket disconnect\n");break;}printf("我已发送\n");}}}}}fclose(fd);free(buf);#ifdef WINclosesocket(st);WSACleanup();#elseclose(st);#endifreturn 1;}SOCKET socket_create(int port){SOCKET st = socket(AF_INET,SOCK_STREAM,0);//初始化socketif(st == 0)return 0;#ifdef WINconst char on = 0;#elseint on = 0;#endifif (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){printf("setsockopt failed %s\n", strerror(errno));return EXIT_FAILURE;}struct sockaddr_in addr;//定义一个IP地址的结构memset(&addr,0,sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(8080);addr.sin_addr.s_addr = htonl(INADDR_ANY);//服务器端程序,需要使用bind将IP与server程序绑定if(bind(st,(struct sockaddr *) &addr,sizeof(addr)) == -1){printf("bind failed %s\n", strerror(errno));return 0;}if(listen(st,20) == -1){printf("listen failed %s\n", strerror(errno));return 0;}printf("listen success\n");return st;}// server端socket开始accept的函数SOCKET socket_accept(SOCKET client_st){struct sockaddr_in client_addr;memset(&client_addr,0,sizeof(client_addr));#ifdef WIN int len = 0;#else unsigned int len = 1;#endif len = sizeof(client_addr); SOCKET listen_st = accept(client_st,(struct sockaddr *) &client_addr,&len);//阻塞调用 if (listen_st == -1) { printf("accept failed %s\n", strerror(errno)); return EXIT_FAILURE; } else { printf("accept by %s\n",inet_ntoa(client_addr.sin_addr)); return listen_st; }}// server端socket在port指定的断口上listen,接收来自client发送的文件int recv_work(int port){SOCKET st = socket_create(port);// 建立server端socket,在port指定的端口listenif(st == 0)return 0;// 如果有client连接到,socket_accept函数返回client的socketSOCKET listen_st = socket_accept(st);if(listen_st == 0)return 0;char *buf = malloc(BUFSIZE);memset(buf,0,BUFSIZE);FILE * fd = NULL;size_t rc = recv(listen_st,buf,BUFSIZE,0);//接收来自client的数据,客户端第一次要发送的文件名称if(rc <= 0){if(rc < 0)printf("receive failed %s\n", strerror(errno));elseprintf("socket disconnect\n");}else{printf("receicing %s\n",buf);fd = fopen(buf,"wb");//以只写的方式打开if(fd == NULL){printf("open %s failed %s\n", buf, strerror(errno));return 0;}else{memset(buf,0,BUFSIZE);strcpy(buf,"OK");rc = send(listen_st,buf,strlen(buf),0);if(rc <= 0){if(rc < 0)printf("send failed %s\n", strerror(errno));elseprintf("socket disconnect\n");}while(1){memset(buf,0,BUFSIZE);rc = recv(listen_st,buf, BUFSIZE, 0);if(rc <= 0)// 如果client连接断开,代表文件传递完成,或者网络意外中断,循环break{if(rc < 0)printf("receive failed %s\n", strerror(errno));elseprintf("socket disconnect\n");break;}else{fwrite(buf,1,rc,fd);// 将从client端收到的内容写入文件}}}}if(fd)fclose(fd);free(buf);#ifdef WIN closesocket(st); closesocket(listen_st); WSACleanup();#else close(st); close(listen_st);#endifreturn 1;}
在windows下的makfile代码:
.SUFFIXES:.c .o CC=gcc SERVERSRCS=file_server.c\ pub.c CLIENTSRCS=file_socket.c\ pub.c SERVEROBJS=$(SERVERSRCS:.c=.o) CLIENTOBJS=$(CLIENTSRCS:.c=.o) SERVEREXEC=server.exe CLIENTEXEC=client.exe all: $(SERVEROBJS) $(CLIENTOBJS) $(CC) -static -o $(SERVEREXEC) $(SERVEROBJS) $(CC) -static -o $(CLIENTEXEC) $(CLIENTOBJS) @echo '----------------ok----------------' .c.o: $(CC) -Wall -DWIN -g -o $@ -c $< clean: rm -f $(SERVEROBJS) rm -f $(CLIENTOBJS) rm -f core*
linux下的makefile文件:
.SUFFIXES:.c .o CC=gcc SERVERSRCS=file_server.c\ pub.c CLIENTSRCS=file_socket.c\ pub.c SERVEROBJS=$(SERVERSRCS:.c=.o) CLIENTOBJS=$(CLIENTSRCS:.c=.o) SERVEREXEC=server CLIENTEXEC=client all: $(SERVEROBJS) $(CLIENTOBJS) $(CC) -o $(SERVEREXEC) $(SERVEROBJS) $(CC) -o $(CLIENTEXEC) $(CLIENTOBJS) @echo '----------------ok----------------' .c.o: $(CC) -Wall -g -o $@ -c $< clean: rm -f $(SERVEROBJS) rm -f $(CLIENTOBJS) rm -f core*
0 0
- linux网络编程之实现跨平台PC之间进行文件传输
- Linux之PC与Linux虚拟机之间的文件传输
- Linux网络编程之socket文件传输示例
- Linux网络编程之socket文件传输示例
- Linux网络编程之socket文件传输示例
- Linux网络编程之socket文件传输示例
- Linux网络编程之socket文件传输示例
- Linux网络编程之SOCKET文件传输
- Linux网络编程之SOCKET文件传输
- Linux网络编程之基于UDP实现可靠的文件传输示例
- java socket 进行两台PC之间的文件传输
- Linux网络编程:socket文件传输
- Linux网络编程学习之---简单局域网FTP文件传输服务器
- Linux网络编程之Tcp/Udp socket文件传输示例
- 使用scp在Linux之间进行文件传输
- iOS之PC与MAC虚拟机之间的文件传输
- Linux网络编程:socket文件传输范例
- Linux网络编程:socket文件传输范例
- Spring学习之第一个AOP程序
- caffe源码深入学习5:超级详细的caffe卷积层代码解析
- nlp研究领域与方法的知识体系
- Java Web之会话技术
- 【POJ1204】Word Puzzles-AC自动机
- linux网络编程之实现跨平台PC之间进行文件传输
- java面向对象各章知识点
- Java
- STL系列之deque双端队列+vector向量容器
- 使用递归打印出一个文件夹下所有子孙文件的树形结构
- 如何使用# ## ... _ _VA_ARGS_ _
- 数据分析师入行指引
- Mycat生产实践---数据迁移与扩容实践
- 多态