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

📄 transportfile.cpp

📁 本代码是基于LINUX系统下的
💻 CPP
字号:
// TransportFile.cpp: implementation of the CTransportFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Client.h"
#include "TransportFile.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTransportFile::CTransportFile()
{

}

CTransportFile::~CTransportFile()
{

}
int CTransportFile::ServerSend( CString FileName )
{
	int nResult = 0;
	
	//1、启动Winsock:对Winsock DLL进行初始化,协商Winsock的版本支持并分配必要的资源。(服务器端和客户端)
	WORD wVersion = MAKEWORD( 2, 0 );
	WSADATA wsData;
	nResult = WSAStartup( wVersion, &wsData );
	if( nResult !=0 )
	{
		return SOCK_WSA_ERR;
	}
	
	//2、创建套接字:(服务器端和客户端)
	SOCKET s = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
	if( s == INVALID_SOCKET )
	{
		return SOCK_CRSOCK_ERR;	 //错误处理
	}
	
	//获取本地IP地址
	char caLocalIp[ 16 ];
	 memset( caLocalIp, 0x00, sizeof( caLocalIp ) );
	 if( !GetLocalIP( caLocalIp ) )
	 {
	       return SOCK_BIND_ERR;
	 }
	 
	//3、套接字的绑定:将本地地址绑定到所创建的套接字上。(服务器端和客户端)
	 
	sockaddr_in addr;
	addr. sin_family =AF_INET;
	addr. sin_port = htons(SVR_PORT); 	//保证字节顺序
	addr. sin_addr.s_addr = inet_addr( caLocalIp );
	nResult = bind( s,( sockaddr* )&addr, sizeof( sockaddr ) );
	if( nResult == SOCKET_ERROR )
	{
		return SOCK_BIND_ERR; 	//错误处理
	}
	
	//4、 套接字的监听:(服务器端)
	nResult = listen( s , 5 );  //最多5个连接
	if( nResult == SOCKET_ERROR )
	{
		return SOCK_LISTEN_ERR; //错误处理
	}
		
	//5、套接字等待连接::(服务器端)
	struct sockaddr_in cliaddr;
	SOCKET s_c;
	int len;
	len = sizeof ( cliaddr );
	//memset( cliaddr , 0x00, len);
		s_c = accept( s, ( sockaddr *)&cliaddr, &len );
		printf( "Connect OK!!!\n" );
		if( s_c == INVALID_SOCKET )
		{
			return SOCK_ACCEPT_ERR; //错误处理
		}
	
		//6、套接字发送数据:(服务器端和客户端)
		nResult = FileSend( &s_c, FileName );
		if( nResult < 0 )
		{
			return nResult;	//错误处理
		}
	
	//7、 关闭套接字:释放所占有的资源。(服务器端和客户端)
	
	nResult = closesocket( s );
	if( nResult == SOCKET_ERROR )
	{
		return SOCK_CLOSE_ERR;	//错误处理
	}
	
	return TRAN_SUCCESS;
}


//-----------------------------------------------------------------------------------------
//发送文件的程序
int CTransportFile::FileSend( SOCKET* s ,CString filename )
{	
	FILE*				stream;
	struct Fileinfo 	fileinfo;
	int					nResult; 

	if( !( stream = fopen(filename, "rb") ) )
	{
		return FILE_ERR;
	} 
	
	//组织文件基本信息准备发送
	memset( &fileinfo, 0x00, sizeof(fileinfo) );
    memcpy( &fileinfo.fileName, filename, sizeof( fileinfo.fileName ) );
	fileinfo.fileBlock = SEND_BUFFER_SIZE;
	long temp = filesize( stream );
	if(temp < SEND_BUFFER_SIZE)
		fileinfo.BlockNum = 1;
	else
		fileinfo.BlockNum = temp / SEND_BUFFER_SIZE + 1;
	fileinfo.fileSize = filesize( stream );
    	
	unsigned int infolen = sizeof( fileinfo );
	do
	{	
		unsigned int len = sizeof( fileinfo );
		nResult = send( *s, (char *)&fileinfo , len , 0 );
		printf("Send Fileinfo OK!!!\n");
		if ( nResult == SOCKET_ERROR )
		{
			return SOCKET_ERROR;	
		}
		infolen -= nResult;
	}
	while( infolen > 0);		//发送文件基本信息
	
	printf( "Now ,Send File Data!!!\n" );
	//发送文件
	BYTE  sendData[SEND_BUFFER_SIZE] ;
	memset( sendData ,0x00 , SEND_BUFFER_SIZE );
	//sendData = new BYTE[SEND_BUFFER_SIZE];		//每次发送指定大小文件包
	int allSendSIZE = filesize( stream );				//要发送文件的整个长度

	int NUM = fileinfo.BlockNum;
	int endNum = temp % SEND_BUFFER_SIZE;
	int ii = 1;
	int jj=1;
	do
	{
		unsigned long  sendThisTime, doneSoFar, buffOffset;
		buffOffset = 0;
		while( !feof( stream ) )
		{	
			if( ii <= NUM)
			{
				memset( sendData ,0x00 , SEND_BUFFER_SIZE );
				fread( sendData, SEND_BUFFER_SIZE, 1, stream);
			}
			else
			{
				memset( sendData ,0x00 , SEND_BUFFER_SIZE );
				fread( sendData, endNum, 1, stream);
			}
			if( allSendSIZE < SEND_BUFFER_SIZE )
				sendThisTime = endNum;
			else
				sendThisTime = SEND_BUFFER_SIZE;
			do
			{
				doneSoFar = send( *s, (char *)sendData, sendThisTime , 0 ); 
				// test for errors and get out if they occurred
				if ( doneSoFar == SOCKET_ERROR )
				{
					return SOCKET_ERROR;
				}
				buffOffset += doneSoFar;
				sendThisTime -= doneSoFar;
				allSendSIZE -= doneSoFar;
			}
			while ( sendThisTime > 0 );
		recv( *s, ( char *)&ii, sizeof(ii), 0 );
		printf("%d\n",jj++);
		}	
	}
	while ( allSendSIZE > 0 );
	
//	delete[]  sendData;
	fclose( stream );
	return TRAN_SUCCESS;
}

// 获得本机IP地址
bool CTransportFile::GetLocalIP( char caIpAddr[] )
{
    char caLocalIp[ 16 ];
    char caHostName[ 100 ];
    int iRtn;
    //unsigned long ulAddrInfo;
    struct hostent s_HostEnt, *pHostEnt;
    struct in_addr s_IpAddr;

    WORD wVerReq;
    WSADATA wsaData;

    wVerReq = MAKEWORD( 2, 0 );
    iRtn = WSAStartup( wVerReq, &wsaData );
    if( iRtn != 0 )
    {
        return false;
    }
    if( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 0 )
    {
        WSACleanup();
        return false;
    }

    memset( caHostName, 0x00, sizeof(caHostName) );
    if( gethostname( caHostName, sizeof(caHostName) ) != 0 )
    {
        WSACleanup();
        return false;
    }

    pHostEnt = &s_HostEnt;
    pHostEnt = gethostbyname( caHostName );
    if( pHostEnt == NULL )
    {
        WSACleanup();
        return false;
    }
    
    memcpy( &s_IpAddr, pHostEnt->h_addr_list[0], sizeof(struct in_addr) );
    memset( caLocalIp, 0x00, sizeof(caLocalIp) );
    strncpy( caLocalIp, inet_ntoa(s_IpAddr), sizeof( caLocalIp ) - 1 );
    strncpy( caIpAddr, caLocalIp, sizeof( caLocalIp ) - 1 );
    
    WSACleanup();

    return true;   
}

void CTransportFile::PrintReturn( int nRet)
{
	switch( nRet )
	{
	case	TRAN_SUCCESS:		AfxMessageBox("TRAN_SUCCESS"); break;			//传输成功
	case	SOCK_WSA_ERR:		AfxMessageBox("SOCK_WSA_ERR"); break;			//启动winsock失败
	case	SOCK_CRSOCK_ERR:	AfxMessageBox("SOCK_CRSOCK_ERR"); break;			//创建套接字失败
	//case	SOCK_BIND_ERR:		AfxMessageBox("SOCK_BIND_ERR"); break;	//绑定端口失败
	case	SOCK_LISTEN_ERR:	AfxMessageBox("SOCK_LISTEN_ERR"); break;		//监听失败
	case	SOCK_ACCEPT_ERR:	AfxMessageBox("SOCK_ACCEPT_ERR"); break;		//等待连接失败
	case	SOCK_SEND_ERR:		AfxMessageBox("SOCK_SEND_ERR"); break;	//发送数据失败
	case	SOCK_CLOSE_ERR:		AfxMessageBox("SOCK_CLOSE_ERR"); break;	//关闭	SOCKET失败
	case	SOCK_RECVE_ERR:		AfxMessageBox("SOCK_RECVE_ERR"); break;	//接受数据失败
	//case	SOCK_CONNECT_ERR:	cout<<"SOCK_CONNECT_ERR"<<endl; break;
	case	FILE_ERR:			AfxMessageBox("FILE_ERR"); break;	//文件错误
	case 	Other_ERR:			AfxMessageBox("Other_ERR"); break;	//其他不明原因
	default:; //AfxMessageBox("NO ERROR");
	}
}

long CTransportFile::filesize(FILE *stream) 
{ 
   long curpos, length; 

   curpos = ftell(stream); 
   fseek(stream, 0L, SEEK_END); 
   length = ftell(stream); 
   fseek(stream, curpos, SEEK_SET); 
   return length; 
} 


⌨️ 快捷键说明

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