我是靠谱客的博主 瘦瘦星月,最近开发中收集的这篇文章主要介绍Socket-tcp-文件和图片的传送,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

// file_client.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include<WinSock2.h>
#include<thread>
#include<fstream>
#pragma comment(lib,"ws2_32.lib")

using namespace std;

//=====================全局常量================
#define port 8901
#define client_ipadd "127.0.0.1"
const int BUFFER_SIZE = 1024;
//=====================全局变量================
SOCKET client;
sockaddr_in saddr;
sockaddr_in caddr;
int slen = sizeof(saddr);
int clen = sizeof(caddr);
char buf[200];
char discon[] = "byebye";
char goon[] = "next";

ifstream fp;

struct File {
	char buffer[BUFFER_SIZE];
	int length;
	int flag;
}file;

//=====================函数声明================
void initSocket();
void getFileName(char path[], char name[]);
void openFile(char path[]);
int getFileLength(char buf[]);
bool choose();
//DWORD WINAPI sendFile_Thread(LPVOID lp);
void sendFile_Thread();

int main()
{
	//初始化listenSer套接字
	initSocket();
	memset(buf, 0, sizeof(buf));
	int irecv=recv(client, buf, sizeof(buf), 0);
	if (irecv == SOCKET_ERROR) {
		::cout << "接收错误!" << endl;
		closesocket(client);
		WSACleanup();
		exit(1);
	}
	::cout <<buf<< endl;
	sendFile_Thread();
		//开始发送文件
		/*HANDLE hsend_Thread = CreateThread(NULL, 0, sendFile_Thread, (LPVOID)&file, 0, NULL);
		if (hsend_Thread == NULL) {
			cout << "线程创建失败" << endl;
		}*/

	
	//CloseHandle(hsend_Thread);
	closesocket(client);
	WSACleanup();
	system("pause");
	return 0;
}

void initSocket() {
	WSADATA wsadata;
	WORD version = MAKEWORD(2, 2);
	if (::WSAStartup(version, &wsadata)) {
		::cout << "加载Socket失败!" << endl;
		system("pause");
		exit(1);
	}

	//创建socket
	client = socket(AF_INET, SOCK_STREAM, 0);
	if (client == INVALID_SOCKET) {
		::WSACleanup();
		system("pause");
		exit(1);
	}

	//初始化地址包
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	//初始化变量
	slen = sizeof(saddr);
	clen = sizeof(caddr);

	if (connect(client, (SOCKADDR*)&saddr, slen)==SOCKET_ERROR) {
		cout << "连接服务器失败!" << endl;
		closesocket(client);
		WSACleanup();
		system("pause");
		exit(1);
	}
}

// 判断文件夹是否存在
BOOL IsDirExist(char cdir[])
{
	string dir(cdir);
	size_t origsize = dir.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(dir.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, dir.c_str(), _TRUNCATE);
	DWORD dwAttrib = GetFileAttributes(wcstring);
	return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

//打开文件函数声明,特别注意是传递引用,不然后续操作会出错
void openFile(char data[]) {
	while (1) {
		cout << "请输入要发送文件的路径: " << endl;
		cin >> data;  //输入图片的绝对路径
		// 以读 / 写方式打开一个二进制文件,只允许读 / 写数据。若图片无法打开,则路径有问题,关闭连接
		fp.open(data, ios::in | ios::binary);
		if (!(fp.is_open())) {
			memset(data, 0, sizeof(data));
			cout << "图片路径出错,请重新尝试!" << endl;
		}
		else {
			break;
		}
	}
}





void getFileName(char path[], char name[]) {
	int len = strlen(path);
	int count = 0;
	for (int i = len; i > 0; i--) {
		if (path[i] != '\') {
			count++;
		}
		else {
			break;
		}
	}
	int j = 0;
	int pos = len - count + 1;
	for (int i = pos; i < len; i++) {
		name[j++] = path[i];
	}
	name[j] = '';
}

int getFileLength(char buf[]) {
	FILE *p;
	int length = 0;

	if ( fopen_s(&p,buf, "rb+")) {
		//计算文件的总长度
		fseek(p, 0, SEEK_END);  //指针移动到图片的最后一个字节;
		length = ftell(p);  //获取图片总长度
		fseek(p, 0, SEEK_SET);  //指针还原到开始位置
		fclose(p);
	}
	else {
		::cout << "文件打开错误" << endl;
	}
	return length;
}

bool choose() {
	int j;
	int isend;
	cout << endl;
	cout << "请选择是否继续发送图片:(1或者2)" << endl;
	cout << "   1: YES     2: NO " << endl;
	cout << "我的选择: ";
	cin >> j;
	if (j == 2) {
		isend = send(client, discon, strlen(discon), 0);
		if (isend == SOCKET_ERROR)
		{
			cout << "发送消息出错!" << endl;
			closesocket(client);
			WSACleanup();
			system("pause");
			exit(1);
		}
		cout << "Clent: " << discon << endl;
		cout << "关闭服务器连接!";
		return  FALSE;
	}
	else {
		isend = send(client, goon, strlen(goon), 0);
		if (isend == SOCKET_ERROR)
		{
			cout << "发送消息出错!" << endl;
			closesocket(client);
			WSACleanup();
			system("pause");
			exit(1);
		}
		cout << "Client: 请接受下一个文件。" << endl;
		return TRUE;
	}
}



void sendFile_Thread() {
	int len = sizeof(buf);
	int irecv = 0;
	int isend = 0;
	while (true) {
		cout << "==========================发送文件=========================" << endl;
		//打开文件
		openFile(buf);
		::cout << "buf=" <<buf<< endl;

		//获取发送图片的名字
		char name[20] = "";
		getFileName(buf, name);
		::cout << "name=" << name << endl;


		//发送名字
		isend = send(client, name, strlen(name), 0);
		if (isend == 0 || isend == SOCKET_ERROR) {
			::cout << "发送文件名错误" << endl;
			closesocket(client);
			WSACleanup();
			system("pause");
			exit(1);
		}

		::cout << "buf=" << buf << endl;
	   // length = getFileLength(buf);
		streampos pos = fp.tellg();
		fp.seekg(0,ios::end);
		cout << "1:" << fp.tellg() << endl;
		int length = fp.tellg();
		fp.seekg(pos);
		cout << "2: length=" << length << endl;
		//分包发送图片,图片长度大于0,循环发送,否则发送完毕,停止发送
		::cout << endl;
		::cout << "····准备发送····" << endl;
		//接收文件
		while (length > 0)
		{
			memset(file.buffer, 0, BUFFER_SIZE);
			fp.read(file.buffer, sizeof(file.buffer));
			int len = sizeof(file.buffer);

			if (length >= len) {
				file.length = len;
				file.flag = 0;
			}
			else {
				file.length = len;
				file.flag = 1;
			}

			isend = send(client, (char*)&file, sizeof(struct File), 0);
			if (isend == 0 || isend == SOCKET_ERROR) {
				::cout << "发送文件出错" << endl;
				closesocket(client);
				WSACleanup();
				fp.close();
				system("pause");
				exit(1);
			}
			else {
				length -= len;
			}
		}
		//接收完成标志
		memset(buf, 0, sizeof(buf));
		irecv = recv(client, buf, sizeof(buf), 0);
		if (irecv == 0 || irecv == SOCKET_ERROR) {
			cout << "接收文件失败!" << endl;
			cout << "断开连接!" << endl;
			closesocket(client);
			WSACleanup();
			system("pause");
			exit(1);
		}
		else {
			cout << "····传送成功····" << endl;
			cout << endl;
		}
		fp.close();
		if (!choose())
			break;
	}
}


// file_server.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include<WinSock2.h>
#include<thread>
#include<fstream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

//=====================全局常量================
#define port 8901
#define ser_ipadd "127.0.0.1"
const int BUFFER_SIZE = 1024;
//=====================全局变量================
SOCKET listenSer;
SOCKET serClient;
sockaddr_in saddr;
sockaddr_in caddr;
int slen = sizeof(saddr);
int clen = sizeof(caddr);
ofstream fp;
char buf[200];

//char recvbuf[BUFFER_SIZE];
//char sendbuf[BUFFER_SIZE];

struct File {
	char buffer[BUFFER_SIZE];
	int length;
	int flag;
}file;
//=====================函数声明================
void initSocket();
char* filePath(char name[]);
void openFile(char path[]);
//DWORD WINAPI recvFile_Thread(LPVOID lp);
void recvFile_Thread();
int main()
{
	//初始化listenSer套接字
	initSocket();

	//接收客户端的请求
	serClient = ::accept(listenSer, (SOCKADDR*)&caddr, &clen);
	if (serClient == INVALID_SOCKET) {
		::cout << "接收连接失败!" << endl;
		::cout << WSAGetLastError() << endl;
		closesocket(serClient);
		WSACleanup();
		system("pause");
		exit(1);
	}
	else {
		::cout << "····连接成功·····" << endl;
		if (send(serClient, "来自服务器:连接成功!", strlen("来自服务器:连接成功!"), 0) == SOCKET_ERROR) {
			cout << "发送失败!" << endl;
		}
	}
	 recvFile_Thread();
		//开始接收文件
		/*HANDLE hrecv_Thread = CreateThread(NULL, 0, recvFile_Thread, (LPVOID)&file, 0, NULL);
		if (hrecv_Thread == NULL) {
			cout << "线程创建失败" << endl;
		}*/

	
	//CloseHandle(hrecv_Thread);
	closesocket(serClient);
	closesocket(listenSer);
	WSACleanup();
	system("pause");
	return 0;
}

void initSocket(){
	WSADATA wsadata;
	WORD version = MAKEWORD(2, 2);
	if (::WSAStartup(version, &wsadata)) {
		::cout << "加载Socket失败!" << endl;
		system("pause");
		exit(1);
	}

	//创建socket
	listenSer = socket(AF_INET, SOCK_STREAM, 0);
	if (listenSer == INVALID_SOCKET) {
		::WSACleanup();
		system("pause");
		exit(1);
	}
	
	//初始化地址包
	saddr.sin_family = AF_INET;
	saddr.sin_port = htons(port);
	saddr.sin_addr.S_un.S_addr = INADDR_ANY;

	//初始化变量
	slen = sizeof(saddr);
	clen = sizeof(caddr);

	//绑定地址到服务器
	int ret = ::bind(listenSer, (SOCKADDR*)&saddr, slen);
	if (ret == SOCKET_ERROR) {
		::cout << "绑定地址失败" << endl;
		closesocket(listenSer);
		WSACleanup();
		system("pause");
		exit(1);
	}

	//监听连接请求,其实还是初始化socket内容
	int li = ::listen(listenSer, 5);
	if (li == SOCKET_ERROR) {
		::cout << "监听失败" << endl;
		::cout << WSAGetLastError() << endl;
		closesocket(listenSer);
		WSACleanup();
		system("pause");
		exit(1);
	}
}

// 判断文件夹是否存在
BOOL IsDirExist(char cdir[])
{
	string dir(cdir);
	size_t origsize = dir.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(dir.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, dir.c_str(), _TRUNCATE);
	DWORD dwAttrib = GetFileAttributes(wcstring);
	return INVALID_FILE_ATTRIBUTES != dwAttrib && 0 != (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}

char* filePath(char name[]) {
	char *dir;
	dir = new char[50];
	while (true)
	{
		::cout << "请输入图片存放路径: " << endl;
		cin >> dir;
		if (IsDirExist(dir)) {
			break;
		}
		else {
			::cout << "文件目录不存在!" << endl;
		}
	}
	int nlen = strlen(name);
	int dlen = strlen(dir);
	for (int j = 0; j < nlen; j++) {
		dir[dlen] = name[j];
		dlen += 1;
	}
	dir[dlen] = '';
	return dir;
}
void openFile(char path[]) {
	// 以读 / 写方式打开或建立一个二进制文件,允许读和写。
	fp.open(path, ios::out | ios::binary);
	if (!(fp.is_open())) {
		::cout << "文件存放路径出错!" << endl;
		closesocket(serClient);
		WSACleanup();
		system("pause");
		exit(1);
	}
	::cout << "存放图片的绝对路径: " << path << endl;
	::cout << endl;

}


//DWORD WINAPI recvFile_Thread(LPVOID lp){
void recvFile_Thread() {
	int len = sizeof(buf);
	char end[] = "ok";
	int irecv = 0;
	int isend = 0;
	while (true)
	{
		cout << "=======================================接收文件=====================================" << endl;
		//接收文件名
		memset(buf, 0, len);
		irecv = recv(serClient, buf, len, 0);
		if (irecv == 0 || irecv == SOCKET_ERROR) {
			::cout << "接收文件名错误" << endl;
			closesocket(serClient);
			WSACleanup();
			system("pause");
			exit(1);
		}
		::cout << "接收的文件名:" << buf << endl;

		//打开文件
		char *path;
		path=filePath(buf);
		openFile(path);
		cout << "····准备接收····" << endl;
		delete path;
		file.flag = 0;

		//接收文件
		while (!file.flag)
		{
			memset(file.buffer, 0, BUFFER_SIZE);
			irecv = recv(serClient, (char*)&file, sizeof(struct  File), 0);
			if (irecv == 0 || irecv == SOCKET_ERROR) {
				cout << "接收文件失败!" << endl;
				cout << "断开连接!" << endl;
				closesocket(serClient);
				WSACleanup();
				system("pause");
				exit(1);
			}
			fp.write(file.buffer, file.length);
			cout << "····接受中····" << endl;
		}

		//发送接收完成标志
		isend = send(serClient, end, strlen(end), 0);
		if (isend == 0 || isend == SOCKET_ERROR) {
			cout << "发送确认信息失败!" << endl;
			cout << "断开连接!" << endl;
			closesocket(serClient);
			WSACleanup();
			system("pause");
			exit(1);
		}
		else {
			cout << "····接收完成····" << endl;
		}
		fp.close();

		//接收是否继续传输的标志
		memset(buf, 0, sizeof(buf));
		irecv = recv(serClient, buf, sizeof(buf), 0);
		if (irecv == 0 || irecv == SOCKET_ERROR) {
			cout << "接收是否继续标志失败!" << endl;
			closesocket(serClient);
			WSACleanup();
			system("pause");
			exit(1);
		}
		if (strcmp(buf, "next") == 0) {
			cout << "准备接收下一个文件。" << endl;
		}
		else {
			cout << "关闭服务器连接" << endl;
			closesocket(serClient);
			WSACleanup();
			system("pause");
			exit(1);
		}
	}
}


在这里插入图片描述
在这里插入图片描述

最后

以上就是瘦瘦星月为你收集整理的Socket-tcp-文件和图片的传送的全部内容,希望文章能够帮你解决Socket-tcp-文件和图片的传送所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部