TCP 协议文件传输示例

一个简单的传输的例子 单线程 阻塞模式.   用 bcc32.exe 可直接编译通过.

 以下是发送端代码

send.cpp

//---------------------------------------------------------------------------

#include <iostream>

#include "winsock2.h"

using namespace std;



#pragma comment(lib , "ws2_32.lib")

//---------------------------------------------------------------------------



WSADATA wsaData;

UINT uTimerID;

DWORD MAX_SIZE = 1024 * 4;

DWORD FinishSize = 0;

DWORD SendSize = MAX_SIZE;

LPSTR SFileName;

DWORD FSize;

DWORD DWSpeed=0;

DWORD OldFinish=0;



MMRESULT (WINAPI *ptimeSetEvent)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);

MMRESULT (WINAPI *ptimeKillEvent)(UINT uTimerID);

HINSTANCE DLLInst;



bool init()

{

	DLLInst=LoadLibrary("winmm.dll");

	if(DLLInst)

    {

		ptimeSetEvent = (MMRESULT (WINAPI *)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent))GetProcAddress(DLLInst, "timeSetEvent");

		if(!ptimeSetEvent) return false;

		ptimeKillEvent = (MMRESULT (WINAPI *)(UINT uTimerID))GetProcAddress(DLLInst, "timeKillEvent");

		if(!ptimeKillEvent) return false;

		return true;

	}

	return false;

}



void Byte2Human(const DWORD & byte)

{

	if(byte < 1024){

		cout << ((float)((int)(byte*100+0.5))/100.0) << "B";

		return;

	}

	float kb = byte/1024;

	if (kb<1024){

		cout << ((float)((int)(kb*100+0.5))/100.0) << "KB";

		return ;

	}

	float mb = kb/1024;

	if (mb<1024){

		cout << ((float)((int)(mb*100+0.5))/100.0) << "MB";

		return;

	}

	float gb = mb/1024;

	cout << ((float)((int)(gb*100+0.5))/100.0) << "GB";

}



void WINAPI TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)

{

	DWSpeed = FinishSize-OldFinish;

	OldFinish = FinishSize;

	cout << '/r';

 	cout << "                                                                              ";

	cout << '/r';

	cout << "文件名:" << SFileName << " " << FinishSize << "/" << FSize << " ";

	Byte2Human(DWSpeed);

	cout << "/S";

}



int main(int argc, char* argv[])

{

	if(!init())

	{

		cout<<"初始化失败"<<endl;

		return 0;

	}

	int ret;

	if(argc < 4)

	{

		cout << "App.exe Host Port FileName" << endl;

		return 0;

	}



	if((ret=WSAStartup(0x0202, &wsaData))!=0)

	{

		cout << "WSAStartup Failed!! Code:" << ret << endl;

		return 0;

	}

	SOCKET sock;

	struct sockaddr_in server;

	sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if(sock==INVALID_SOCKET)

	{

		cout << "创建socket出错" << endl;

		return 0;

	}

	server.sin_family=AF_INET;

	server.sin_port=htons(atoi(argv[2]));

	server.sin_addr.s_addr=inet_addr(argv[1]);

	cout << "正在连接 " << argv[1] << ":" << argv[2] << endl;

	if(connect(sock, (struct sockaddr *)&server, sizeof(server))==SOCKET_ERROR)

	{

		cout << "连接失败" << endl;

		return 0;

	}

	cout << "连接成功" << endl;



	//打开文件准备发送

	HANDLE hFile;

	OFSTRUCT ofs;

	HANDLE hMap;

	void *pVoid;

	SFileName = argv[3];

	hFile=(HANDLE)OpenFile(argv[3], &ofs, OF_READWRITE | OF_SHARE_DENY_NONE);

	if((HFILE)hFile==HFILE_ERROR)

	{

		cout << "打开文件失败 ErrorCode=" << GetLastError() << endl;

		return 0;

	}

	FSize=GetFileSize((HANDLE)hFile, NULL);

	hMap=CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);

	if(hMap==NULL)

	{

		cout << "打开映射失败 ErrorCode=" << GetLastError() << endl;

		return 0;

	}

	pVoid=MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);

	if(pVoid==NULL)

	{

		cout << "映射数据失败 ErrorCode=" << GetLastError() << endl;

		return 0;

	}

	char *p = (char *)pVoid;

	cout << "正在发送文件 " << argv[3] << endl;

	uTimerID=ptimeSetEvent(1000, 0, (LPTIMECALLBACK)TimeProc, NULL, TIME_PERIODIC|TIME_CALLBACK_FUNCTION);



	while(1)

	{

		if(FSize - FinishSize < MAX_SIZE)

		{

			SendSize = FSize - FinishSize;

		}

		int ret = send(sock, p+FinishSize, SendSize, 0);

		if(ret == SOCKET_ERROR )

		{

			cout << endl << "Ret=" << ret << " ErrorCode=" << WSAGetLastError() << endl;

			return 0;

		}

		FinishSize += ret;

		if(FinishSize == FSize) break;

	}

	closesocket(sock);

	ptimeKillEvent(uTimerID);

	CloseHandle(hMap);

	CloseHandle(hFile);

	cout << endl;

	cout << "完成 发送数据量:" << FinishSize << endl;

	return 0;

}

//---------------------------------------------------------------------------
 
以下是接收端代码
recv.cpp
//---------------------------------------------------------------------------

#include <iostream>
#include "winsock2.h"
using namespace std;


#pragma comment(lib , "ws2_32.lib")

//---------------------------------------------------------------------------



WSADATA wsaData;

DWORD FinishSize = 0;

DWORD OldFinish=0;

DWORD DWSpeed=0;

UINT uTimerID;



MMRESULT (WINAPI *ptimeSetEvent)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent);

MMRESULT (WINAPI *ptimeKillEvent)(UINT uTimerID);

HINSTANCE DLLInst;



bool init()

{

	DLLInst=LoadLibrary("winmm.dll");

	if(DLLInst)

    {

		ptimeSetEvent = (MMRESULT (WINAPI *)(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD dwUser, UINT fuEvent))GetProcAddress(DLLInst, "timeSetEvent");

		if(!ptimeSetEvent) return false;

		ptimeKillEvent = (MMRESULT (WINAPI *)(UINT uTimerID))GetProcAddress(DLLInst, "timeKillEvent");

		if(!ptimeKillEvent) return false;

		return true;

	}

	return false;

}



void Byte2Human(const DWORD & byte)

{

	if(byte < 1024){

		cout << ((float)((int)(byte*100+0.5))/100.0) << "B";

		return;

	}

	float kb = byte/1024;

	if (kb<1024){

		cout << ((float)((int)(kb*100+0.5))/100.0) << "KB";

		return ;

	}

	float mb = kb/1024;

	if (mb<1024){

		cout << ((float)((int)(mb*100+0.5))/100.0) << "MB";

		return;

	}

	float gb = mb/1024;

	cout << ((float)((int)(gb*100+0.5))/100.0) << "GB";

}



void CALLBACK TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)

{

	DWSpeed = FinishSize-OldFinish;

	OldFinish = FinishSize;

	cout << '/r';

 	cout << "                                                                              ";

	cout << '/r';

	cout << "已接收 " << FinishSize << " ";

	Byte2Human(DWSpeed);

	cout << "/S";

}



int main(int argc, char* argv[])

{

	if(!init())

	{

		cout<<"初始化失败"<<endl;

		return 0;

	}



	int ret;

	if(argc < 3)

	{

		cout << "App.exe Port NewFileName" << endl;

		return 0;

	}



	HANDLE hFile;

	OFSTRUCT ofs;

	HANDLE hMap;

	void *pVoid;

	hFile=(HANDLE)OpenFile(argv[2], &ofs, OF_CREATE | OF_READ);

	if((HFILE)hFile==HFILE_ERROR)

	{

		cout << "打开文件失败";

		ret = GetLastError();

		cout << " ErrorCode=" << ret << endl;

		return 0;

	}



	if((ret=WSAStartup(0x0202, &wsaData))!=0)

	{

		cout << "WSAStartup Failed!! Code:" << ret << endl;

		return 0;

	}



	SOCKET sock, ssock;

	struct sockaddr_in fsin, sin;

	int alen;



	memset(&sin, 0, sizeof(sin));

	sin.sin_family=AF_INET;

	sin.sin_addr.s_addr=inet_addr("");

	sin.sin_port=htons(atoi(argv[1]));

	sock=socket(PF_INET, SOCK_STREAM, 0);

	if(sock==INVALID_SOCKET)

	{

		cout << "创建socket出错" << endl;

		return 0;

	}

	if(bind(sock, (struct sockaddr*)&sin, sizeof(sin))==SOCKET_ERROR)

	{

		cout << "帮定Socket失败" << endl;

		return 0;

	}

	if(listen(sock, SOMAXCONN)==SOCKET_ERROR)

	{

		cout << "监听失败" << endl;

		return 0;

	}

	cout << "正在监听... 端口" << argv[1] << endl;

	alen=sizeof(struct sockaddr);

	ssock=accept(sock, (struct sockaddr *)&fsin, &alen);

	if(ssock==INVALID_SOCKET)

	{

		cout << "接受请求失败" << endl;

		return 0;

	}

	closesocket(sock);

	char buf[4096];

	DWORD dwWrite;

	cout << "连接已建立" << endl;

	uTimerID=ptimeSetEvent(1000, 0, (LPTIMECALLBACK)TimeProc, NULL, TIME_PERIODIC|TIME_CALLBACK_FUNCTION);



	while(1)

	{

		memset(buf, 0x00, 4096);

		ret = recv(ssock, buf, 4096, 0);

		if(ret == SOCKET_ERROR )

		{

			cout << endl << "接收数据量:" << FinishSize << endl;

			cout << "Ret=" << ret;

			ret = WSAGetLastError();

			cout << " ErrorCode=" << ret << endl;

			return 0;

		}

		if(ret == 0)

		{

			cout << endl << "连接已断开" << endl;

			break;

		}

		FinishSize += ret;

		if(!WriteFile(hFile, buf, ret, &dwWrite, NULL))

		{

			cout << "写文件失败" << endl;

			return 0;

		}



	}

	ptimeKillEvent(uTimerID);

	closesocket(sock);

	CloseHandle(hFile);

	cout << endl;

	cout << "完成 接收数据量:" << FinishSize << endl;

	return 0;

}

//---------------------------------------------------------------------------

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值