通过socket实现网络文件传输

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
}

猜你喜欢

转载自blog.csdn.net/zhao5502169/article/details/89741698