C ++ implementation file transfer

Referring to this production, not essentially transfer files, but uses TCP to transfer files content, then special treatment, I think it is very clever.

https://blog.csdn.net/luairan/article/details/38413193

Basically no mistake, is to change under BUFFERSIZE, do not remove the package, there is not some socket send me into a socket pointer, and very grateful to the children's shoes (hey are seniors), good design is very clever.

I slightly changed the location of the next cycle, so do not be reconnected after each transfer a file. Available impress the code

server

#include <WINSOCK2.H>
#include <stdio.h>
#include <iostream>
#include <windows.h>
//#include "package.h"
#pragma comment (lib,"ws2_32.lib")
using namespace std;
#define BUFFERLENGTH 4096
#define SERVERPORT 8888
char * getByteFromFile(FILE * fp, char buf[], int start, int length) {
	int sign;
	int c;
	int i = 0;
	char set[6];
	c = getc(fp);

	while (!feof(fp) && i<BUFFERLENGTH - 2)//-1
	{
		*(buf + i) = c;
		i++;
		c = getc(fp);
	}
	if (feof(fp))
	{
		set[0] = '0';
		buf[i] = '\0';
	}
	else
	{
		set[0] = '1';
		buf[i] = c;
	}
	buf[i + 1] = '\0';

	int f = 1000;
	for (int j = 1; j<5; j++)
	{
		set[j] = strlen(buf) / f % 10 + '0';
		f = f / 10;
	}
	set[5] = '\0';
	//cout << "in the function the sendbuf is " << buf << endl;
	//cout << "in the funtion the set/head is" << set << endl;
	return set;
}

DWORD WINAPI serverFunction(LPVOID parameter) {
	//SOCKET acceptSock = (SOCKET)parameter;
	SOCKET *ClientSocket = (SOCKET*)parameter;
	char RecvBuf[BUFFERLENGTH + 1];//接收
	char SendBuf[BUFFERLENGTH + 1];//接收

	strcpy(SendBuf, "hello!");
	printf("Send:%s\n", SendBuf);
	send(*ClientSocket, SendBuf, strlen(SendBuf) + 1, 0);
	memset(SendBuf, 0, sizeof(SendBuf));
	while (1) {
		printf("----------------------------------\n\n");
		int receByt = recv(*ClientSocket, RecvBuf, sizeof(RecvBuf), 0);
		/*int len = recv(acceptSock, receiveBuf, sizeof(receiveBuf) - 1, 0);
		receiveBuf[len] = '\0';
		printf("recv:%s\n", receiveBuf);*/
		if (receByt>0) {
			cout << "接收到的消息是:" << RecvBuf << "            来自客户端:" << *ClientSocket << endl;
			printf("\n");
			// cout<<receByt<<endl;
		}
		else
		{
			cout << "接收消息结束!客户端离开" << endl;
			printf("\n");
			cout << "----------------------------------" << endl;
			break;
		}
		//将收到数据变为文件名
		FILE * fp;
		if (strcmp(RecvBuf, "") == 0) return -1;
		//查找文件是否存在

		string fileName = RecvBuf;
		fileName = "F:\\VS代码\\FTP服务器\\备用文件\\" + fileName;
		if ((fp = fopen(fileName.c_str(), "r")) == NULL)
		{
			printf("不能打开文件 %s\n", RecvBuf);

			send(*ClientSocket, "99999", 6, 0);
		}

		else {
			//传输文件
			char * head = (char*)malloc(sizeof(char)*(5 + BUFFERLENGTH + 1));
			do
			{
				memset(SendBuf, 0, sizeof(SendBuf));
				strcpy(head, getByteFromFile(fp, SendBuf, 0, BUFFERLENGTH));
				//printf("SendBuf is %s\n", SendBuf);
				strcat(head, SendBuf);
				//printf("Head is %s\n",head);
				send(*ClientSocket, head, strlen(head) + 1, 0);
				Sleep(40);
			} while (head[0] == '1');
			fclose(fp);
		}
	}
	
	return 0;

}
int main() {
	system("color f0");
	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
	WORD wOldColorAttrs;
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;

	// Save the current color
	GetConsoleScreenBufferInfo(h, &csbiInfo);
	wOldColorAttrs = csbiInfo.wAttributes;

/*----------------------------------------------------------*/
	WSADATA WSAdata;
	SOCKET listenSock, acceptSock;
	SOCKADDR_IN addr_in;
	WORD versionRequest;
	versionRequest = MAKEWORD(2, 2);
	int err;
	err = WSAStartup(versionRequest, &WSAdata);
	if (err) {
		cout << "Error: WSAStartup()!" << endl;
	}
	if ((listenSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
	{
		printf("error:  WSASocket()! error_number:%d", WSAGetLastError());
		return 1;
	}
	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons(SERVERPORT);
	addr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	int n = bind(listenSock, (sockaddr*)&addr_in, sizeof(sockaddr));
	if (n == SOCKET_ERROR)
	{
		printf(" Failed bind() \n");
		return -1;
	}
	listen(listenSock, 20);
	cout << "服务端准备就绪,等待连接请求" << endl;
	SOCKADDR_IN clientsocket;
	int len = sizeof(SOCKADDR);
	cout << "server startup sucessful" << endl;
	while (1) {
		SOCKET *ClientSocket = new SOCKET;
		ClientSocket = (SOCKET*)malloc(sizeof(SOCKET));
		//接收客户端连接请求
		int SockAddrlen = sizeof(sockaddr);
		*ClientSocket = accept(listenSock, 0, 0);
		cout << "一个客户端已连接到服务器,socket是:" << *ClientSocket << endl;
		CreateThread(NULL, 0, &serverFunction, ClientSocket, 0, NULL);
	}
	WSACleanup();//释放资源的操作
	return -1;
}

Client

#include <WINSOCK2.H>
#include <stdio.h>
#include <iostream>
#include<string>
#include<io.h>
//#include "package.h"
#pragma comment(lib,"ws2_32.lib")
#define BUFFERLENGTH 4096
using namespace std;

int getBytesLength(char* buf) {
	char len[5];
	for (int i = 1; i<5; i++) {
		len[i - 1] = buf[i];
	}
	len[4] = '\0';
	return atoi(len);
}
int main(int argc, char **argv)
{
	system("color f0");
	int err;
	WORD versionRequired;
	WSADATA wsaData;
	versionRequired = MAKEWORD(1, 1);
	char str[30];
	int segema = 0;
	err = WSAStartup(versionRequired, &wsaData);//协议库的版本信息
	printf("正在连接服务器!\n");
	char receiveBuf[BUFFERLENGTH + 6];
	char sendBuf[BUFFERLENGTH + 1];


	//while(1){
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//0
	SOCKADDR_IN clientsock_in;
	clientsock_in.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	clientsock_in.sin_family = AF_INET;
	clientsock_in.sin_port = htons(8888);
	segema=connect(clientSocket, (SOCKADDR*)&clientsock_in, sizeof(SOCKADDR));//开始连接
	if(segema== SOCKET_ERROR)
	{
		cout << "Connect Error::" << GetLastError() << endl;
		return -1;

	}
	else
	{
		cout << " 连接成功 !" << endl;

	}
	memset(receiveBuf, 0x00, sizeof(receiveBuf));
		//cout << "aaaa" << endl;
	segema=recv(clientSocket, receiveBuf, sizeof(receiveBuf), 0);
		//cout << segema << endl;
	if (segema == 0||segema==SOCKET_ERROR)
	{
		cout << "接收失败!";
	}
	else {
		cout << "接收到:" << receiveBuf << endl;
	}
	segema++;
	while (1) {
		memset(receiveBuf, 0x00, sizeof(receiveBuf));
		printf("-----------------------------\n");
		printf("请输入文件名,输入quit退出\n");
		cin >> str;
		if (strcmp(str, "quit") == 0)
		{
			//break;
			return 0;
		}
		int len = strlen(str) + 1;
		send(clientSocket, str, len, 0);
		printf("请输入文件保存的路径:(输入1默认保存到F:\\VS代码\\FTP客户端\\下载文件)\n");
		string path;
		cin >> path;
		if (path=="1") {
			path = "F:\\VS代码\\FTP客户端\\下载文件";
			//cout << path << endl;
		}
		string spath = path + "\\" ;
		spath += str;
		//cout << spath << endl;
		FILE *outfp;
		if ((outfp = fopen(spath.c_str(), "w")) == NULL)
		{
			cout << "不能保存该文件:  " << spath << endl;
			continue;
			//exit(2);
		}
		int bytesize = 0;
		while (1)
		{
			int len = recv(clientSocket, receiveBuf, BUFFERLENGTH + 5, 0);
			receiveBuf[BUFFERLENGTH + 5] = '\0';
			if (len>0)
			{
				int flag = getBytesLength(receiveBuf);
				if (flag>0)
				{
					if (flag == strlen(receiveBuf) - 5)
					{
						bytesize += flag;
						printf("\b\b\b\b\b\b\b\b\b\\b\b\b\b\b\b\b\b\b\b\b已接收%d% Byte", bytesize);
						for (int i = 5; i<strlen(receiveBuf); i++)
						{
							putc(receiveBuf[i], outfp);
						}
					}
					if (receiveBuf[0] == '0'&&flag == strlen(receiveBuf) - 5)
					{
						printf("\n\n文件%s下载完成\n\n\n", str);
						fclose(outfp);
						break;
					}
					if (receiveBuf[0] == '9')
					{
						printf("文件%s不存在!\n", str);
						fclose(outfp);
						remove(spath.c_str());
						//segema = 1;
						break;
					}
				}
			}
		}
		
	}
		
	closesocket(clientSocket);

	
	WSACleanup();
	system("pause");
	return 0;
}

 

Published 32 original articles · won praise 5 · Views 4662

Guess you like

Origin blog.csdn.net/qq_38941327/article/details/89279348