📄 transportfile.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 + -