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

📄 winsockdlg.cpp

📁 P2P网络编程,实现多线程网络文件传输程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    
    do
    {    
        //向主窗口发送消息主要用于控制进度条
		::PostMessage(hwnd,UM_PRGRECV,0,(LPARAM)cbLeftToReceive);
		int iiGet, iiRecd;
		
        iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? 
cbLeftToReceive : RECV_BUFFER_SIZE ;
        iiRecd = recv(sockConn, (char*)recdData, iiGet,0 );
		
        
        if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
        {
            int iErr = ::GetLastError();
            TRACE( "GetFileFromRemoteSite returned a socket error while getting chunked file data\n"
                "\tNumber of Bytes received (zero means connection was closed) = %d\n"
                "\tGetLastError = %d\n", iiRecd, iErr );
            
			
            
            bRet = FALSE;
            goto PreReturnCleanup;
        }
		
        
        destFile.Write( recdData, iiRecd); 
        cbLeftToReceive -= iiRecd;
		
    } 
    while ( cbLeftToReceive > 0 );
	
	::PostMessage(hwnd,UM_PRGROVER,0,0);   //向主窗口发送消息
	
PreReturnCleanup:						   //文件接收结束标签
    
    delete[] recdData;					   //释放内存
    
    if ( bFileIsOpen )
        destFile.Close();
	
    
    closesocket(sockConn);
	closesocket(socketrecv);
    
    return bRet;
	
}



DWORD WINAPI CWinSockDlg::SocketSend(LPVOID lpParameter)
{
	//将参数传递给本地变量
	HWND hwnd=((socksend*)lpParameter)->hwnd;
    CString sendfname=((socksend*)lpParameter)->sendfname;
	DWORD dwip=((socksend*)lpParameter)->dwip;
	
	SOCKET socketsend=socket(AF_INET,SOCK_STREAM,0);//创建Socket
	
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr=htonl(dwip);
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(8848);
	
	int ret1;
	ret1=connect(socketsend,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//连接指定地址
	
    if(SOCKET_ERROR==ret1)
	{
		closesocket(socketsend);
		::MessageBox(hwnd,"连接失败!","警告",MB_OK);
		return FALSE;
	}
	
	
	::PostMessage(hwnd,UM_PRGSBGN,0,0);				//向主窗口发送消息


    //声明用于文件发送的本地变量
	BOOL bRet = TRUE;
    
    int fileLength, cbLeftToSend;
    
    
    BYTE* sendData = NULL;
	
    CFile sourceFile;
    CFileException fe;
    BOOL bFileIsOpen = FALSE;
    

	//打开参数传递进来的文件用于发送
    if( !( bFileIsOpen = sourceFile.Open( sendfname, 
		CFile::modeRead | CFile::typeBinary, &fe ) ) )
    {
        TCHAR strCause[256];
        fe.GetErrorMessage( strCause, 255 );
        TRACE( "SendFileToRemoteRecipient encountered an error while opening the local file\n"
			"\tFile name = %s\n\tCause = %s\n\tm_cause = %d\n\tm_IOsError = %d\n",
			fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );
        
        
        
        bRet = FALSE;
        goto PreReturnCleanup;
    }
	
    
	//首先传递将要被发送文件的长度给接收端
    fileLength = sourceFile.GetLength();
    fileLength = htonl( fileLength );
	
    cbLeftToSend = sizeof( fileLength );
	
    do
    {
        int cbBytesSent;
        BYTE* bp = (BYTE*)(&fileLength) + sizeof(fileLength) - cbLeftToSend;
        cbBytesSent = send(socketsend, (const char*)bp, cbLeftToSend,0 );
        
        
        if ( cbBytesSent == SOCKET_ERROR )
        {
            int iErr = ::GetLastError();
            TRACE( "SendFileToRemoteRecipient returned a socket error while sending file length\n"
                "\tNumber of Bytes sent = %d\n"
                "\tGetLastError = %d\n", cbBytesSent, iErr );
            
            
			
            bRet = FALSE;
            goto PreReturnCleanup;
        }
        
        
        cbLeftToSend -= cbBytesSent;
    }
    while ( cbLeftToSend>0 );
    
    
    //开始发送晚间
    sendData = new BYTE[SEND_BUFFER_SIZE]; 
    
    cbLeftToSend = sourceFile.GetLength();
    
    do
    {
        ::PostMessage(hwnd,UM_PRGSEND,0,(LPARAM)cbLeftToSend);
        
        int sendThisTime, doneSoFar, buffOffset;
        
        sendThisTime = sourceFile.Read( sendData, SEND_BUFFER_SIZE );
        buffOffset = 0;
        
        do
        {
            
			
			doneSoFar = send(socketsend,(const char*) (sendData + buffOffset), 
				sendThisTime,0 ); 
            
            
            if ( doneSoFar == SOCKET_ERROR )
            {
                int iErr = ::GetLastError();
                TRACE( "SendFileToRemoteRecipient returned a socket error while sending chunked file data\n"
					"\tNumber of Bytes sent = %d\n"
					"\tGetLastError = %d\n", doneSoFar, iErr );
				
				
				
				bRet = FALSE;
				goto PreReturnCleanup;
            }
            
            
            
            buffOffset += doneSoFar;
            sendThisTime -= doneSoFar;
            cbLeftToSend -= doneSoFar;
        }
        while ( sendThisTime > 0 );
        
    }
    while ( cbLeftToSend > 0 );
    
	
	::PostMessage(hwnd,UM_PRGSOVER,0,0);//向主窗口发送消息发送完毕
    
    PreReturnCleanup:					//结束标签后释放内存
    
    
    
    
    delete[] sendData;
    
    if ( bFileIsOpen )
        sourceFile.Close();
	
	
	closesocket(socketsend);
    
    return bRet;
	
	
}



void CWinSockDlg::OnOpen() 
{
	
	CFileDialog fileDlg(TRUE);				//创建打开文件对话框
    fileDlg.m_ofn.lpstrTitle="打开文件";
	fileDlg.m_ofn.lpstrFilter="All Files(*.*)\0*.*\0\0"; //设定筛选
	if(IDOK==fileDlg.DoModal())
	{
		m_sendfname=fileDlg.GetPathName();     
		]
		//如果用户选择确定设置发送文件名并对对话框显示做响应调整
	
	    (GetDlgItem(IDC_EDIT1))->SetWindowText(m_sendfname);
	
	    (GetDlgItem(IDC_EDITSEND))->SetWindowText("准备好发送");
	    Invalidate();
	}
	
	
}

void CWinSockDlg::OnRecv() 
{
	sockrecv* sr=new sockrecv;	//声明一个接收参数结构体
	sr->hwnd=m_hWnd;			//将主窗口句柄传送给它
	HANDLE handl=CreateThread(NULL,0,SocketRecv,(LPVOID)sr,0,NULL);//创建线程用于接收
	CloseHandle(handl);
	
}

void CWinSockDlg::OnSend() 
{
    socksend* ss=new socksend;  //声明一个发送参数结构体
	
	//取得IP地址控件上的地址值,设定发送文件名,传递主窗口句柄
	((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS1))->GetAddress(ss->dwip);
    ss->sendfname=m_sendfname;
	ss->hwnd=m_hWnd;
	
	HANDLE handl=CreateThread(NULL,0,SocketSend,(LPVOID)ss,0,NULL);
	CloseHandle(handl);
	
}

afx_msg void CWinSockDlg::onprgrecv(WPARAM wParam,LPARAM lParam)
{
    //控制接收进度条的消息响应函数
	int prgnow=(int)lParam;				//将剩余接收字节作为参数传递给函数
	if(m_beginprgrecv)					//判断是否第一次接到此消息
	{
		m_prgrecv.SetRange32(0,prgnow); //设置进度条范围
        m_prgrecvpre=prgnow;			//给成员变量赋值	
		m_beginprgrecv=FALSE;			//改变标志
	}
    int thistran=m_prgrecvpre-prgnow;   //本次传输字节数
	int now=m_prgrecv.GetPos();         //先前的总传输量
	m_prgrecv.SetPos(thistran+now);		//设置进度条位置

}

afx_msg void CWinSockDlg::onprgrover(WPARAM wParam,LPARAM lParam)
{
	//恢复接收状态
	m_prgrecv.SetPos(0);
	m_prgrecvpre=0;
    m_beginprgrecv=TRUE;

	(GetDlgItem(IDC_EDITRECV))->SetWindowText("尚未准备好接收");
    
}

afx_msg void CWinSockDlg::onprgsend(WPARAM wParam,LPARAM lParam)
{
	//请参考接收消息响应函数解释
	int prgnow=(int)lParam;
	if(m_beginprgsend)
	{
		m_prgsend.SetRange32(0,prgnow);
        m_prgsendpre=prgnow;
		m_beginprgsend=FALSE;
	}
    int thistran=m_prgsendpre-prgnow;
	int now=m_prgsend.GetPos();
	m_prgsend.SetPos(thistran+now);

}

afx_msg void CWinSockDlg::onprgsover(WPARAM wParam,LPARAM lParam)
{
	//恢复发送状态
	m_prgsend.SetPos(0);
	m_prgsendpre=0;
    m_beginprgsend=TRUE;
	(GetDlgItem(IDC_EDITSEND))->SetWindowText("尚未准备好发送");
}


afx_msg void CWinSockDlg::onprgrrdy(WPARAM wParam,LPARAM lParam)
{
(GetDlgItem(IDC_EDITRECV))->SetWindowText("准备好接收");//UM_PRGRRDY消息响应
}

afx_msg void CWinSockDlg::onprgrbgn(WPARAM wParam,LPARAM lParam)
{
(GetDlgItem(IDC_EDITRECV))->SetWindowText("开始接收");  //UM_PRGRBGN消息响应

}
afx_msg void CWinSockDlg::onprgsbgn(WPARAM wParam,LPARAM lParam) //UM_PRGSBGN消息响应
{
(GetDlgItem(IDC_EDITSEND))->SetWindowText("开始发送");
}

⌨️ 快捷键说明

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