Socket网络编程:文件传输
客户端发送文件名给服务器,服务器接受文件名,将对应的文件发送给客户端
基于TCP的Linux文件传输
客户端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_ ) (_) \n"); printf(" \n"); /* 客户端接收文件 */ } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { binner(); menue(); exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } //步骤1:调用socket函数创建客户端TCP套接字; printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); int tsock; tsock = socket(AF_INET,SOCK_STREAM,0); if(tsock < 0) { printf("创建socket失败!\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器端套接字的端点地址(即服务器端的IP地址和协议端口号);然后,调用connect函数向远程服务器端发起TCP连接建立请求; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int ret; ret = connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); if(ret < 0) { printf("连接失败!\n"); exit(-1); } //步骤3:在与服务器端成功地建立了TCP连接之后,调用send()函数将缓冲区中的数据从套接字发送给该远程服务器端; char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); //向服务器发送buffer中的数据,buffer中放的是文件的名字 int num = 0; num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //步骤4:调用recv()函数从套接字读取服务器端发送过来的数据并存入缓冲区; FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } memset(buffer,'\0',my_BUFSIZ); num = 0; while(num = recv(tsock,buffer,my_BUFSIZ,0)!=0) { if(num < 0) { printf("接收数据失败!\n"); break; } int write_len = fwrite(buffer,sizeof(char),my_BUFSIZ,fp); //printf("接收文件长度:%d\n",num); if(write_len!=my_BUFSIZ) { printf("文件:%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } printf("接收文件:%s成功\n",file_name); fclose(fp); //步骤5:与服务器端交互完毕,调用close()函数将套接字关闭,释放所占用的系统资源。 close(tsock); return 0; }
服务器:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> int SERVER_PORT = 23335 ; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); /* 服务器发送文件 */ } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { binner(); menue(); exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //步骤1:调用socket()函数创建服务器端TCP主套接字; int msock; msock = socket(AF_INET,SOCK_STREAM,0); if(msock<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该TCP套接字绑定到本机的一个可用的端点地址; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); int ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤3:调用lsten函数将该TCP套接字设为被动模式,并设置等待队列的长度; #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!\n"); exit(-1); } while(1) { //步骤4:调用accept()函数从该TCP套接字上接收一个新客户连接请求,并且在与该客户之间成功建立了TCP 连接之后,为该TCP连接创建个新的从套接字 (由该新套接字来负责与客户之间进行实际的通信); int ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock<0) { printf("接收数据失败\n"); exit(-1); } //步骤5:基于新创建的从套接字,调用recv(函数从套接字读取客户发送过来的数据并存入缓冲区; char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); if(recv(ssock, buffer, sizeof(buffer), 0)<0) { printf("接收文件名失败\n"); exit(-1); } else { printf("请求文件名>>%s\n",buffer); } //步骤6:基于新创建的从套接字,调用send()函 数将缓冲区中的数据从套接字发送给该远程客户: char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); //将文件名从缓冲区buffer拷贝到文件名数组里面 strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer)); FILE * fp=fopen(file_name,"r"); if(fp==NULL) { printf("文件:%s不存在\n",file_name); } else { memset(buffer,'\0',my_BUFSIZ); int file_block_length=0; while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0) { printf("文件块大小:%d\n",file_block_length); if(send(ssock,buffer,file_block_length,0)<0) { printf("文件:%s 发送失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%s 成功\n",file_name); } //步骤7:与客户交互完毕,调用close()函数将从套接字关闭,释放所占用的系统资源; close(ssock); } //步骤8:与所有客户交互完毕,调用close()函数将主套接字关闭,释放所占用的系统资源 close(msock); return 0; }
基于UDP的Linux文件传输
服务器:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> #include <netinet/in.h> #include <stdlib.h> int my_BUFSIZ=4096; int SERVER_PORT=23334; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【UDP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //步骤1: 调用socket()函数创建服务器端UDP套接字; int msocket; msocket = socket(AF_INET,SOCK_DGRAM,0); if(msocket<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址; int ret; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); ret=bind(msocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in)); if(ret<0) { printf("服务器绑定端口:%d失败",SERVER_PORT); exit(-1); } //步骤3:调用recvfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; while(1) { char buf[my_BUFSIZ]; memset(buf,'\0',sizeof(buf)); struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); if(recvfrom(msocket, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("请求文件名>>%s\n",buf); } //步骤4:基于保存的远程客户端的套接字端点地址,调用sendto函数将缓冲区中的数据从该UDP套接字发送给该远程客户端; char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); //将文件名从缓冲区buf拷贝到文件名数组里面 strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf)); FILE * fp=fopen(file_name,"r"); if(fp==NULL) { printf("文件:%s不存在\n",file_name); } else { memset(buf,'\0',my_BUFSIZ); int file_block_length=0; while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0) { printf("文件块大小:%d\n",file_block_length); if(sendto(msocket,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf)) { printf("文件:%s 发送失败\n",file_name); break; } memset(buf,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%s 成功\n",file_name); } } //步骤5:与客户交互完毕,调用close()函数将该 UDP套接字关闭,释放所占用的系统资源。 close(msocket); return 0; }
客户端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【UDP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //步骤1:调用socket()函数创建客户端UDP套接字; int tsock; tsock = socket(AF_INET,SOCK_DGRAM,0); if(tsock < 0) { printf("创建套接字失败\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器的IP地址和协议端口号,然后再调用sendto()函数将缓冲区中的数据从UDP套接字发送给远程服务器端; char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int len = sizeof(struct sockaddr_in); //printf("buffer:%d",strlen(buffer)); int send_to=sendto(tsock,buffer,strlen(buffer),0,(struct sockaddr*)&servaddr,len); printf("%d,%d",send_to,strlen(buffer)); if(send_to != strlen(buffer)) { printf("发送数据失败\n"); exit(-1); } FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } int num = 0; char buf[my_BUFSIZ]; memset(buf,'\0',my_BUFSIZ); struct sockaddr_in clientaddr; memset(&clientaddr,0,sizeof(struct sockaddr_in)); memset(buf,'\0',sizeof(buf)); //步骤3:调用revfrom()函数从该UDP套接字接收来自远程服务器端的数据并存入缓冲区; while(num = recvfrom(tsock,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len) !=0) { if( num< 0) { printf("接收数据失败\n"); exit(-1); } int write_len = fwrite(buf,sizeof(char),my_BUFSIZ,fp); //printf("接收文件长度:%d\n",num); if(write_len!=my_BUFSIZ) { printf("文件:%s写入失败\n",file_name); break; } memset(buf,'\0',my_BUFSIZ); } printf("接收文件:%s成功\n",file_name); fclose(fp); close(tsock); return 0; }
基于UDP的Windows文件传输:
客户端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Linux】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【UDP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //初始化Winsock DLL int ret; WORD sockertVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(sockertVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //创建socket SOCKET tsocket = socket(AF_INET, SOCK_DGRAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //绑定和发送数据 char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); int num=0; int len = sizeof(struct sockaddr_in); num = sendto(tsocket,buffer, strlen(buffer) , 0, (struct sockaddr*)&servaddr, len); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //接收数据 FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } char buf[my_BUFSIZ]; ZeroMemory(buf,sizeof(buf)); num=0; struct sockaddr_in clientaddr; ZeroMemory(&clientaddr,sizeof(clientaddr)); while(num = recvfrom(tsocket,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len)!=0) { if(num<0) { printf("接收数据失败"); exit(-1); } int write_len = fwrite(buf,sizeof(char),my_BUFSIZ,fp); //printf("接收文件长度:%d\n",num); if(write_len!=my_BUFSIZ) { printf("文件:%s写入失败\n",file_name); break; } memset(buf,'\0',my_BUFSIZ); }; printf("接收文件:%s成功\n",file_name); closesocket(tsocket); WSACleanup(); system("pause"); return 0; }
服务器:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int my_BUFSIZ=4096; int SERVER_PORT=23334; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Windows】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【UDP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //步骤1:使用WSAStartup函数初始化Winsock DLL; WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket函数创建服务器端UDP套接字; SOCKET msock; msock = socket(AF_INET, SOCK_DGRAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); if(bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))< 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } while(1) { //步骤4:调用revfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; char buf[my_BUFSIZ]; ZeroMemory(buf,sizeof(buf)); struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); int num = recvfrom(msock, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len); if(num<0) { printf("接收数据失败\n"); exit(-1); } else { printf("请求文件名>>%s\n",buf); } //步骤5:基于保存的远程客户端的套接字端点地址,调用sendto()函 数将缓冲区中的数据从该UDP套接字发送给该远程客户端; char file_name[FILE_NAME_MAX_SIZE+1]; ZeroMemory(file_name,sizeof(file_name)); strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf)); FILE * fp=fopen(file_name,"r"); if(fp==NULL) { printf("文件:%s不存在\n",file_name); } else { ZeroMemory(buf,sizeof(buf)); int file_block_length=0; while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0) { printf("文件块大小:%d\n",file_block_length); if(sendto(msock,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf)) { printf("文件:%s 发送失败\n",file_name); break; } memset(buf,'\0',my_BUFSIZ); } fclose(fp); printf("发送文件:%s 成功\n",file_name); } } //步骤6:与客户交互完毕,调用closesocket()函数将该UDP套接字关闭,释放所占用的系统资源; closesocket(msock); //步骤7:最后,调用WSACleanup0函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
基于TCP的Window文件传输:
客户端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Windows】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); //步骤1:使用WSAStartup()函数初始化Winsock DLL; int ret; WORD socketVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(socketVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建客户端TCP套接字; SOCKET tsocket = socket(AF_INET, SOCK_STREAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:找到期望与之通信的远程服务器端套接字的端点地址(即远程服务器端的IP地址和协议端口号), //然后再调用connect()函数向远程服务器端发起TCP连接建立请求; struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); if(connect(tsocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))<0) { printf("连接失败!"); exit(-1); } //步骤4:在与服务器端成功地建立了TCP连接之后, //调用send()函数将缓冲区中的数据从该TCP套接字发送给该远程服务器端; char file_name[FILE_NAME_MAX_SIZE+1]; memset(file_name,'\0',sizeof(file_name)); printf("输入文件名>>"); gets(file_name); char buffer[my_BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name)); // char *buffer="这里是客户端~"; int num=0; num = send(tsocket,buffer, strlen(buffer),0); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } FILE *fp = fopen(file_name,"w"); if(fp==NULL) { printf("文件:%s不可打开\n",file_name); exit(-1); } //步骤5:调用recv()函数从该TCP套接字读取服务器端发送过来的数据并存入缓冲区; ZeroMemory(buffer,sizeof(buffer)); num = 0; while(num = recv(tsocket,buffer,sizeof(buffer),0)!=0) { if(num<0) { printf("接收数据失败\n"); exit(-1); } int write_len = fwrite(buffer,sizeof(char),my_BUFSIZ,fp); printf("接收文件长度:%d\n",num); if(write_len!=my_BUFSIZ) { printf("文件:%s写入失败\n",file_name); break; } memset(buffer,'\0',my_BUFSIZ); } printf("接收文件:%s成功\n",file_name); fclose(fp); //步骤6:与服务器端交互完毕,调用closesocket()函数将该 TCP套接字关闭并释放所占用的系统资源; closesocket(tsocket); //步骤7:最后,调用WSACleanup()函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
服务器端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int my_BUFSIZ=4096; int SERVER_PORT=23334; int FILE_NAME_MAX_SIZE=512; void binner() { printf(" 【文件传输助手:Windows】 \n"); printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } void menue() { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); printf("-f:文件最大,默认512\n"); } int main(int argc,char *argv[]) { binner(); menue(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { exit(-1); } else { for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-f")==0) { FILE_NAME_MAX_SIZE=atoi(argv[i+1]); } } } } printf("\n【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE); WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建服务器端TCP主套接字; SOCKET msock; msock = socket(AF_INET, SOCK_STREAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将TCP主套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤4:调用listen()函数将该TCP主套核字设为被动模式,并设置等待队列长度: #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!"); exit(-1); } //步骤5:调用accpet()函数从该TCP主套接字上接收一个新的客户 TCP连接请求, //并在与该客户之间成功建立了TCP连接之后,为该TCP连接创建一一个新的从套接字 //(由该新的从套接字来负责与客户之间进行实际的通信); while(1) { SOCKET ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock==INVALID_SOCKET) { printf("接收数据失败\n"); exit(-1); } //步骤6:基于新创建的从套接字,调用recv()函数利用 该从套接字读取客户端发送过来的数据并存入缓冲区; char buf[my_BUFSIZ]; ZeroMemory(buf,sizeof(buf)); if(recv(ssock, buf, sizeof(buf), 0)<0) { printf("接收文件名失败\n"); exit(-1); } else { printf("请求文件名>>%s\n",buf); } //步骤7:基于新创建的从套接字,调用send()函数将缓冲区中的数据利用该从套接字发送给该远程客户端; //char *buffer="这里是服务器~"; char file_name[FILE_NAME_MAX_SIZE+1]; ZeroMemory(file_name,sizeof(file_name)); //将文件名从缓冲区buffer拷贝到文件名数组里面 strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf)); FILE * fp=fopen(file_name,"r"); if(fp==NULL) { printf("文件:%s不存在\n",file_name); } else { ZeroMemory(buf,my_BUFSIZ); int file_block_length=0; while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0) { if(send(ssock,buf,file_block_length,0)<0) { printf("文件:%s 发送失败\n",file_name); break; } ZeroMemory(buf,my_BUFSIZ); } fclose(fp); printf("发送文件:%s 成功\n",file_name); } //步骤8:与客户交互完毕,调用closesocket()函数将该从套接字关闭,释放所占用的系统资源); closesocket(ssock); //步骤9:最后,当与所有客户交互完毕之后,调用closesocket()函数将TCP主套接字关闭, //释放所古用的系统资源,然后,再调用WSACleanup()函数来结束Winsock Socket API } closesocket(msock); WSACleanup(); system("pause"); return 0; }