我是靠谱客的博主 悲凉奇迹,最近开发中收集的这篇文章主要介绍利用tcp实现简单的服务器/客户端文件传输,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

利用tcp协议进行简单的c/s模式的文件传输。

利用了流式套接字实现服务器和客户端之间的文件传输

要求:

服务器端和客户端是控制台应用程序

服务器端启动后从键盘输入要发送文件存放的位置和文件名

客户端启动之后输入服务器的ip地址,与服务器建立连接

建立连接后下载服务器提供的文件,并保存到本地

服务器:


#include "pch.h"
#include <iostream>
#include"fstream"
#include"winsock2.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
struct filel {                 //定义储存文件信息的结构体
	char fileName[255];  //文件名
	long int filesize;   //文件大小
};
int main()
{
	SOCKET sock_server,newsock;
	struct sockaddr_in addr, addr_client;
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		cout << "加载动态连接库失败!" << endl;
		return 0;
	}
	char filePath[500];       //用于存放要传输的文件的传输路径
	cout << "文件路径:" << endl;
	cin.getline(filePath, 500);
	if ((sock_server = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		cout << "套接字创建失败!" << endl;
		WSACleanup();
		return 0;
	}
	int addr_len = sizeof(struct sockaddr_in);
	memset((void*)&addr, 0, addr_len);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(60000);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(sock_server, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		cout << "地址绑定失败!" << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	if (listen(sock_server, 0) != 0) {
		cout << "监听套接字调用失败!" << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	else
		cout << "listen......" << endl;
	if ((newsock = accept(sock_server, (struct sockaddr*)&addr_client, &addr_len)) == INVALID_SOCKET) {
		cout << "接收客户端连接失败!" << endl;
		closesocket(sock_server);
		WSACleanup();
		return 0;
	}
	cout << "连接成功!" << endl;
	char rec[3], buffer[1000]; //定义接收确认消息的缓冲区和发送缓冲区
	struct filel file;          //定义保存文件名和文件长度的结构体变量
	ifstream inFile(filePath, ios::in | ios::binary);//定义文件对象并打开文件
	if (!inFile.is_open()) {
		cout << "文件打开失败!" << filePath << endl;
		closesocket(sock_server);//文件打开失败就退出户
		WSACleanup();
		return 0;
	}
	unsigned int size = strlen(filePath);
	while (filePath[size] != '\'&&size > 0)size--;                                      
	strcpy_s(file.fileName, filePath + size);
	inFile.seekg(0, ios::end);    //将文件位置指针移到文件末尾
	size = inFile.tellg();        //获取当前文件的位置指针,即为文件长度
	file.filesize = htonl(size);   //将文件长度存入filesize里
	send(newsock, (char*)&file, sizeof(file), 0);
	if (recv(newsock, rec, sizeof(rec), 0) <= 0) {
		cout << "接收确认信息失败!" << endl;
		closesocket(sock_server);
		closesocket(newsock);
		WSACleanup();
		return 0;
	}
	if (strcmp(rec, "ok") == 0) {
		inFile.seekg(0, ios::beg);  //将文件位置指针返回到头文件
		while (!inFile.eof()) {
			inFile.read(buffer, sizeof(buffer));
			size = inFile.gcount();   //获取实际读取的字节数
			send(newsock, buffer, size, 0);

		}
		cout << "文件传输结束!" << endl;
		inFile.close();
	}
	else
		cout << "无法接收文件!" << endl;
	closesocket(sock_server);
	closesocket(newsock);
	WSACleanup();
	return 0;

}

客户端:


#include "pch.h"
#include <iostream>
#include"fstream"
#include"winsock2.h"
#include"WS2tcpip.h"
#include"direct.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
struct filel {
	char fileName[255];
	int fileSize;
};
int main() {
	SOCKET sock_client;
	struct sockaddr_in addr;
	int addr_len = sizeof(struct sockaddr_in);
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		cout << "加载动态连接库失败!" << endl;
		return 0;
	}
	if ((sock_client = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		cout << "套接字创建失败!" << endl;
		WSACleanup();
		return 0;
	}
	char IP[20];
	cout << "请输入服务器IP:" << endl;
	cin >> IP;
	in_addr a;
	inet_pton(AF_INET, IP, &a);
	memset((void*)&addr, 0, addr_len);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(60000);
	addr.sin_addr.s_addr = a.S_un.S_addr;
	if (connect(sock_client, (struct sockaddr*)&addr, addr_len) != 0) {
		cout << "连接失败!" << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	cout << "连接成功!" << endl;
	// * * * 定义传输文件所需要的变量
	struct filel file;
	long int filelen;
	char filePath[500]= "E:\";
	char sen[3]="ok";
	char buffer[1000];     //接收文件的数据缓冲区
	_mkdir(filePath);     //_mkdir()用于创建文件夹
	if ((filelen = recv(sock_client, (char*)&file, sizeof(file), 0)) <= 0) {
		cout << "未接收到文件名及文件长度!" << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	filelen = ntohl(file.fileSize);
	strcat_s(filePath, file.fileName);
	ofstream outFile(filePath, ios::out | ios::binary);
	if (!outFile.is_open()) {
		cout << "文件不能打开!" << filePath << endl;
		closesocket(sock_client);
		WSACleanup();
		return 0;
	}
	send(sock_client, sen, sizeof(sen), 0);
	int size = 0;
	do {
		size = recv(sock_client, buffer, sizeof(buffer), 0);
		if (size <= 0)break;
		outFile.write(buffer, size);
		filelen -= size;
	} while (filelen > 0);
	if (filelen == 0) {
		cout << "文件传输完毕!" << endl;
	}
	else
		cout << "文件传输失败!" << endl;
	outFile.close();
	closesocket(sock_client);
	WSACleanup();
	return 0;

}

最后

以上就是悲凉奇迹为你收集整理的利用tcp实现简单的服务器/客户端文件传输的全部内容,希望文章能够帮你解决利用tcp实现简单的服务器/客户端文件传输所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部