⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basesocket.cpp

📁 a self encapsulated socket lib
💻 CPP
字号:
#include "BaseSocket.h"
#include <iostream>
#include <string>
#include <stdio.h>
#include <sstream>

const char* BaseSocket::IP_ADDRESS = "127.0.0.1";


inline std::tr1::shared_ptr<FILE> getfd(std::string filename, std::string mode)
{
	std::tr1::shared_ptr<FILE> fd(fopen(filename.c_str(), mode.c_str()), fclose);	
	return fd;
}

inline std::string getsubstr(std::string& data, int& i , int& j)
{
	char c = '\1';
	i = j + 1; j = data.find(c, i);
	if ( j == data.npos) return "";
	return data.substr(i, j - i);
}


inline void decode_task(std::string data, Task& task)
{	
	int i = 0, j = -1;
	getsubstr(data, i, j);
	task.id = atoi(getsubstr(data, i, j).c_str());	
	strcpy(task.title, getsubstr(data, i, j).c_str());
	strcpy(task.content, getsubstr(data, i, j).c_str());
	strcpy(task.pubDate, getsubstr(data, i, j).c_str());
	strcpy(task.dlDate, getsubstr(data, i, j).c_str());	
	task.priority = atoi(getsubstr(data, i, j).c_str());
	task.dtoRemind = atoi(getsubstr(data, i, j).c_str());
}

inline std::string encode_task(std::string istrct, Task task)
{
	std::stringstream ss;
	ss << istrct;
	ss << '\1';
	ss << task.id;
	ss << '\1';
	ss << task.title;
	ss << '\1';
	ss << task.content;
	ss << '\1';
	ss << task.pubDate;
	ss << '\1';
	ss << task.dlDate;
	ss << '\1';
	ss << task.priority;
	ss << '\1';
	ss << task.dtoRemind;
	ss << '\1';
	ss << istrct;	
	return ss.str();	
}

BaseSocket::BaseSocket(void) : AddrLen(sizeof(m_serverAddr))
{
}

BaseSocket::~BaseSocket(void)
{
}

int BaseSocket::SendBuff(SOCKET socket, const char SendBuffer[]) //send the data stored in SendBuffer
{	
	int len = strlen(SendBuffer);	
	int cur = 0;
	while (len > 0) {
		int Ret = send(socket, &SendBuffer[cur], MAX_PATH, 0);
		cur += MAX_PATH;
		len -= MAX_PATH;
		if (Ret == SOCKET_ERROR) return BaseSocket::ERR;
	}
	return 0;
}
int BaseSocket::RecvBuff(SOCKET socket, char RecvBuffer[])		//receive data and store in RecvBuffer
{
	memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
	return recv(socket, RecvBuffer, MAX_PATH, 0);			
}

bool ReceiveTask(std::string data)	//save received task to local
{
	std::tr1::shared_ptr<FILE> fd = getfd("task.dat", "ab");
	if (NULL == fd.get()) return false;
	Task task;
	decode_task(data, task);
	if (1 != fwrite(&task, sizeof(Task), 1, fd.get())) return false;
	return true;
}

int GetInstruction(std::string str, std::string& icode)  //extract instruction from str
{
	int i = str.find('\1', 0);

	if (i != str.npos){	
		icode = str.substr(0, i);
		if(icode.compare("st") == 0) return 1; //send task to client
		if(icode.compare("ft") == 0) return 2; //fetch task from server
	}
	return -1;
}

bool InstructionEnd(std::string data, std::string icode)
{
	int i = data.find_last_of('\1');
	++i;
	if (i != data.npos && data.substr(i).compare(icode) == 0)
		return true;
	return false;
}

//data contains the username of the user start the request
int SendTaskFromLocal(SOCKET socket, std::string data)
{
	int i = 0, j = -1;
	getsubstr(data, i, j); //neglect instruction
	std::string username = getsubstr(data, i, j);
	std::string filename =  username + "_task.dat";
	std::tr1::shared_ptr<FILE> fd = getfd(filename.c_str(), "rb");
	
	while (!feof(fd.get())) {		
		Task task;
		if (fread(&task, sizeof(Task), 1, fd.get()) != 1) break;
		std::string task_str = encode_task("st", task);
		BaseSocket::SendBuff(socket, task_str.c_str()); //send the task
	}		
	fd = getfd(filename.c_str(), "wb"); //clear the task file in server of the user
	return 0;
}

//used to listen for any requests after establishing a connection 
DWORD WINAPI BaseSocket::RecvThread(LPVOID lpParameter)
{
	SOCKET ClientSocket = (SOCKET)lpParameter;   
	char RecvBuffer[MAX_PATH];
	int istrct = -1;
	bool iend = false;
	std::string icode = "";	
	while ( true ){
		std::stringstream ss;
		int Ret = RecvBuff(ClientSocket, RecvBuffer);
		if ( Ret == 0 || Ret == SOCKET_ERROR ) {
			return Ret;
		}

		if (-1 != istrct && !iend){ // check for the end of the instruction
			iend = InstructionEnd(RecvBuffer, icode);
		}

		if (-1 == istrct){ //check for an instruction
			istrct = GetInstruction(RecvBuffer, icode);
			iend = InstructionEnd(RecvBuffer, icode);			
		}		

		if ( -1 != istrct) ss << RecvBuffer; //gather received data

		if (iend) {
			switch(istrct){
				case 1: ReceiveTask(ss.str()); break;	// receive task from server
				case 2: SendTaskFromLocal(ClientSocket, ss.str()); break;  //respond to the fetch task request
			}			
			istrct = -1;
			iend = false;
		}			
	}
}


int BaseSocket::Receive(const SOCKET& socket)	//start a thread to listen to request
{
	HANDLE hThread = CreateThread(NULL, 0, RecvThread, (LPVOID)socket, 0, NULL);
	if ( hThread == NULL )
	{
		throw "Create Thread Failed!";		
	}
	CloseHandle(hThread);
	return 0;
}

int BaseSocket::Startup()
{
	//Init Windows Socket
	if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 ){
		throw "Init Windows Socket Failed!";	
	}
	return 0;
}

int BaseSocket::Cleanup()
{	
	WSACleanup();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -