版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhao5502169/article/details/89741698
把Linux下文件传输和Linux做服务端以及windows做客户端的传输都实现了一遍。
Linux下Server端
Linux下打开文件的函数open(path,flag)
打开模式有
- O_CREAT 必要时创建文件
- O_TRUNC 删除全部现有数据
- O_APPEND 维持现有数据,保存其后面
- O_RDONLY 以只读打开
- O_WRONLY 以只写打开
- O_RDWR 读写打开
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define BUF_SIZE (1024)
#define NAME_SIZE (256)
void error_handling(const char *message);
int main(int argc,char *argv[]){
int serv_sock;
int clnt_sock;
int str_len;
int fd;
struct sockaddr_in serv_addr;
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size;
char buf[BUF_SIZE],name[NAME_SIZE];
if(argc != 2){
printf("Usage :%s <port>\n",argv[0]);
exit(1);
}
serv_sock = socket(PF_INET,SOCK_STREAM,0);
if(serv_sock == -1)
error_handling("socket() error");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) == -1)
error_handling("bind() error");
if(listen(serv_sock,5) == -1)
error_handling("listen() error");
clnt_addr_size = sizeof(clnt_addr);
clnt_sock = accept(serv_sock,(struct sockaddr*) &clnt_addr,&clnt_addr_size);
if(clnt_sock == -1)
error_handling("accept() error");
str_len = read(clnt_sock,name,NAME_SIZE);
if(str_len == -1)
error_handling("read() error");
//printf("original path:%s\n",name);
strcat(name,".copy");//在文件名末尾加上.copy
//printf("current path:%s\n",name);
fd = open(name,O_CREAT|O_WRONLY);
if(fd == -1)
error_handling("open() error");
else
printf("open success..");
while(true){
str_len = read(clnt_sock,buf,BUF_SIZE);
if(str_len == 0)//read读到文件结尾会返回0
break;
write(fd,buf,str_len);
}
close(clnt_sock);
close(serv_sock);
return 0;
}
void error_handling(const char *message){
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
Linux下Client端
open()打开的方式
ios::app: 以追加的方式打开文件
ios::ate: 文件打开后定位到文件尾,ios:app就包含有此属性
ios::binary: 以二进制方式打开文件,缺省的方式是文本方式。两种方式的区别见前文
ios::in: 文件以输入方式打开(文件数据输入到内存)
ios::out: 文件以输出方式打开(内存数据输出到文件)
ios::nocreate: 不建立文件,所以文件不存在时打开失败
ios::noreplace:不覆盖文件,所以打开文件时如果文件存在失败
ios::trunc: 如果文件存在,把文件长度设为0
可以用“或”把以上属性连接起来,如ios::out|ios::binary
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#define BUF_SIZE (1024)
#define NAME_SIZE (256)
void error_handling(const char *message);
int main(int argc,char *argv[]){
int sock;
struct sockaddr_in serv_addr;
char buf[BUF_SIZE],name[NAME_SIZE],message[BUF_SIZE];
int str_len;
int fd;
if(argc != 3){
printf("Usage : %s <IP> <port>\n",argv[0]);
exit(1);
}
sock = socket(PF_INET,SOCK_STREAM,0);
if(sock == -1)
error_handling("socket() error");
memset(&serv_addr,0,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
serv_addr.sin_port = htons(atoi(argv[2]));
if(connect(sock,(struct sockaddr*) &serv_addr,sizeof(serv_addr)) == -1)
error_handling("connect() error");
printf("Enter path:");
if(scanf("%s",name) == -1)
error_handling("read path error");
printf("path:%s\n",name);
write(sock,name,NAME_SIZE);
fd = open(name,O_RDONLY);
if(fd == -1)
error_handling("open() error");
while(true){
str_len = read(fd,buf,BUF_SIZE);
if(str_len == 0)
break;
write(sock,buf,str_len);
}
printf("cp over");
close(sock);
close(fd);
return 0;
}
void error_handling(const char *message){
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}
Windows下Client端
#include<stdio.h>
#include<stdlib.h>
#include<fstream>
#include<WinSock2.h>
#define NAME_SIZE (256)
#define BUF_SIZE (1024)
using namespace std;
void ErrorHandling(const char* message);
int main(int argc, char* argv[]) {
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char buf[BUF_SIZE],name[NAME_SIZE];
int str_Len;
if (argc != 3) {
printf("Usage :%s <IP> <PORT>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error");
hSocket = socket(PF_INET, SOCK_STREAM, 0);
if (hSocket == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(hSocket, (SOCKADDR*)& servAddr, sizeof(servAddr)) == SOCKET_ERROR)
ErrorHandling("connect() error");
printf("Enter path:");
if (scanf("%s", name) == -1)
ErrorHandling("scanf() error");
if (send(hSocket, name, strlen(name) + 1, 0) == -1)
ErrorHandling("send() name error");
ifstream in(name, ios::binary);
if (!in.is_open())
ErrorHandling("open() error");
while (!in.eof()) {
in.read(buf, BUF_SIZE);
send(hSocket, buf, in.gcount(), 0);
}
printf("copy end");
in.close();
closesocket(hSocket);
WSACleanup();
return 0;
}
void ErrorHandling(const char* message) {
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}