當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]c++ 使用socket實(shí)現(xiàn)C/S端文件的下載傳輸首先是服務(wù)器端,大致說(shuō)下流程:服務(wù)器創(chuàng)建線程去處理應(yīng)答accept(),當(dāng)接受到客戶(hù)端連接請(qǐng)求時(shí),首先獲取要發(fā)送的指定的文件數(shù)據(jù)總大小給客戶(hù)端,接著就

c++ 使用socket實(shí)現(xiàn)C/S端文件的下載傳輸
首先是服務(wù)器端,大致說(shuō)下流程:服務(wù)器創(chuàng)建線程去處理應(yīng)答accept(),當(dāng)接受到客戶(hù)端連接請(qǐng)求時(shí),首先獲取要發(fā)送的指定的文件數(shù)據(jù)總大小給客戶(hù)端,接著就是循環(huán)讀取要發(fā)送的文件數(shù)據(jù)流向客戶(hù)端發(fā)送文件數(shù)據(jù),每次都判斷循環(huán)讀取到的數(shù)據(jù)實(shí)際大小,當(dāng)實(shí)際讀取到的數(shù)據(jù)總大小為0時(shí),表示文件發(fā)送結(jié)束。下面是服務(wù)器server端實(shí)現(xiàn):

聲明部分:


public:
??? afx_msg void OnBnClickedButton1();
public:
??? BOOL InitSocket();??? //初始化并創(chuàng)建套接字

??? static DWORD WINAPI ThreadProc(LPVOID lpParameter);??? //創(chuàng)建線程去執(zhí)行服務(wù)器accept()
實(shí)現(xiàn)部分:


void CSendFileServerDlg::OnBnClickedButton1()
{
??? // TODO: 在此添加控件通知處理程序代碼
??? if (InitSocket())
??? {
??????? GetDlgItem(IDC_EDIT1)->SetWindowText(_T("服務(wù)器開(kāi)啟監(jiān)聽(tīng)。。。 rn"));

??????? //創(chuàng)建線程
??????? HANDLE hThread = CreateThread(NULL,0,ThreadProc,NULL,0,NULL);
??????? //關(guān)閉該接收線程句柄,釋放引用計(jì)數(shù)
??????? CloseHandle(hThread);
??? }
}

BOOL CSendFileServerDlg::InitSocket()
{
??? //加載套接字庫(kù)
??? WORD wVersionRequested;
??? WSADATA wsaData;
??? int err;
??? wVersionRequested = MAKEWORD( 1, 1 );
??? err = WSAStartup( wVersionRequested, &wsaData );
??? if ( err != 0 )
??? {
??????? return FALSE;
??? }

??? if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
??? {
??????????? WSACleanup( );
??????????? return FALSE;
??? }

??? //創(chuàng)建套接字
??? //SOCKET m_socket=socket(AF_INET,SOCK_STREAM,0);
??? m_socket=socket(AF_INET,SOCK_STREAM,0);
??? if (m_socket == INVALID_SOCKET)
??? {
??????? AfxMessageBox(_T("套接字創(chuàng)建失??!"));
??????? return FALSE;
??? }

??? SOCKADDR_IN addrSrv;
??? addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
??? addrSrv.sin_family=AF_INET;
??? addrSrv.sin_port=htons(8099);

??? err = bind(m_socket,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));??? //綁定本地端口
??? if (err==SOCKET_ERROR)
??? {
??????? closesocket(m_socket);
??????? AfxMessageBox(_T("綁定失??!"));
??????? return FALSE;
??? }
??? listen(m_socket,5);//開(kāi)啟監(jiān)聽(tīng)

??? return TRUE;

}

DWORD WINAPI CSendFileServerDlg::ThreadProc(LPVOID lpParameter)
{
??? SOCKADDR_IN addrClient;
??? int len = sizeof(SOCKADDR);

??? while (true)
??? {
??????? SOCKET sockConn=accept(m_socket,(SOCKADDR*)&addrClient,&len);

??????? CString filename = _T("E:\test.zip");
??????? HANDLE hFile;
??????? unsigned long long file_size = 0;

??????? char Buffer[1024];
??????? DWORD dwNumberOfBytesRead;

??????? hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
??????? file_size = GetFileSize(hFile,NULL);
??????? send(sockConn,(char*)&file_size,sizeof(unsigned long long)+1,NULL);

??????? do
??????? {
??????????? ::ReadFile(hFile,Buffer,sizeof(Buffer),&dwNumberOfBytesRead,NULL);
??????????? ::send(sockConn,Buffer,dwNumberOfBytesRead,0);
??????? } while (dwNumberOfBytesRead);


??????? CloseHandle(hFile);
??? }

??? return 0;
}
如代碼所述? 每次發(fā)送單位是unsigned char[1024]大小(程序是char 應(yīng)該為unsigned char[1024])所以就不存在網(wǎng)絡(luò)字節(jié)序問(wèn)題也不用考慮大端小端什么的。

服務(wù)器端暫時(shí)不支持多客戶(hù)端并發(fā)訪問(wèn),后續(xù)可能會(huì)加上。。。

-------------------------------------------

下面是客戶(hù)端,同樣也大致說(shuō)下客戶(hù)端流程,客戶(hù)端增加手動(dòng)填寫(xiě)Ip地址和端口號(hào)功能(端口號(hào)暫為8099)。以及下載傳輸文件數(shù)據(jù)進(jìn)度條的顯示,和下面簡(jiǎn)單的一些狀態(tài)顯示。客觀端由填寫(xiě)的IP地址進(jìn)行連接服務(wù)器操作,如果客戶(hù)端連接服務(wù)器成功的話(huà)直接就會(huì)獲取服務(wù)器端發(fā)送的要發(fā)送的文件數(shù)據(jù)的總大小,如果獲取文件總大小>0 則會(huì)循環(huán)往指定的路徑寫(xiě)數(shù)據(jù)啦。此處循環(huán)寫(xiě)文件結(jié)束標(biāo)志,我是用每次實(shí)際寫(xiě)的累加如果累計(jì)值等于從服務(wù)器端獲取的文件總大小的話(huà)表示下載文件數(shù)據(jù)成功,結(jié)束循環(huán)。大致是這樣一個(gè)過(guò)程。代碼實(shí)現(xiàn):

客戶(hù)端聲明部分:

?public:
??? afx_msg void OnBnClickedButton1();
?
??? BOOL InitSocket();
??? void ConnectServer();
??? void ConnectRecvFileData(DWORD ip,int port);
?
private:
??? CProgressCtrl *m_progress; //進(jìn)度條

?進(jìn)度條在OnInitDialog()里初始化:

按 Ctrl+C 復(fù)制代碼
BOOL CRecvFileClientDlg::OnInitDialog()
{
??? CDialog::OnInitDialog();

??? // 將“關(guān)于...”菜單項(xiàng)添加到系統(tǒng)菜單中。

??? // IDM_ABOUTBOX 必須在系統(tǒng)命令范圍內(nèi)。
??? ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
??? ASSERT(IDM_ABOUTBOX < 0xF000);

??? CMenu* pSysMenu = GetSystemMenu(FALSE);
??? if (pSysMenu != NULL)
??? {
??????? CString strAboutMenu;
??????? strAboutMenu.LoadString(IDS_ABOUTBOX);
??????? if (!strAboutMenu.IsEmpty())
??????? {
??????????? pSysMenu->AppendMenu(MF_SEPARATOR);
??????????? pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
??????? }
??? }

??? // 設(shè)置此對(duì)話(huà)框的圖標(biāo)。當(dāng)應(yīng)用程序主窗口不是對(duì)話(huà)框時(shí),框架將自動(dòng)
??? //? 執(zhí)行此操作
??? SetIcon(m_hIcon, TRUE);??????????? // 設(shè)置大圖標(biāo)
??? SetIcon(m_hIcon, FALSE);??????? // 設(shè)置小圖標(biāo)

??? // TODO: 在此添加額外的初始化代碼

??? m_progress = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);
??? m_progress->SetPos(0);

??? return TRUE;? // 除非將焦點(diǎn)設(shè)置到控件,否則返回 TRUE
}
按 Ctrl+C 復(fù)制代碼
客戶(hù)端具體實(shí)現(xiàn)部分:

按 Ctrl+C 復(fù)制代碼
void CRecvFileClientDlg::OnBnClickedButton1()
{
??? // TODO: 在此添加控件通知處理程序代碼
??? ConnectServer();
???
}


BOOL CRecvFileClientDlg::InitSocket()
{
??? //加載套接字庫(kù)
??? WORD wVersionRequested;
??? WSADATA wsaData;
??? int err;
??? wVersionRequested = MAKEWORD( 1, 1 );
??? err = WSAStartup( wVersionRequested, &wsaData );
??? if ( err != 0 )
??? {
??????? return FALSE;
??? }

??? if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
??? {
??????? WSACleanup( );
??????? return FALSE;
??? }

??? return TRUE;

}

void CRecvFileClientDlg::ConnectRecvFileData(DWORD ip,int port)
{
???
??? unsigned long long file_size=0;
??? SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);
??? SOCKADDR_IN addrSrv;
??? addrSrv.sin_addr.S_un.S_addr=htonl(ip);
??? addrSrv.sin_port=ntohs(port);
??? addrSrv.sin_family = AF_INET;
??? //connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
??? //recv(sockClient,(char*)&file_size,sizeof(unsigned long long)+1,NULL);

??? if (!connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
??? {
??????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T(""));
??????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T("連接服務(wù)器成功!rn"));

???????

??????? recv(sockClient,(char*)&file_size,sizeof(unsigned long long)+1,NULL);

??????? unsigned short maxvalue = file_size;??? //此處不太穩(wěn)妥 當(dāng)數(shù)據(jù)很大時(shí)可能會(huì)出現(xiàn)異常
??????? m_progress->SetRange(0,maxvalue);

??????? if (file_size>0)
??????? {
??????????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T(""));
??????????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T("文件下載到本地 d:\test.zip rn"));

??????????? DWORD dwNumberOfBytesRecv=0;
??????????? DWORD dwCountOfBytesRecv=0;
??????????? char Buffer[1024];
??????????? CString filename = _T("d:\test.zip");
??????????? HANDLE hFile;
??????????? hFile = CreateFile(filename,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

??????????? do
??????????? {
??????????????? m_progress->SetPos(dwCountOfBytesRecv);//更新進(jìn)度條

??????????????? dwNumberOfBytesRecv = ::recv(sockClient,Buffer,sizeof(Buffer),0);
??????????????? ::WriteFile(hFile,Buffer,dwNumberOfBytesRecv,&dwNumberOfBytesRecv,NULL);
??????????????? dwCountOfBytesRecv += dwNumberOfBytesRecv;???????????????
??????????? } while (file_size - dwCountOfBytesRecv);


??????????? CloseHandle(hFile);
???????????
??????????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T(""));
??????????? GetDlgItem(IDC_SHOWINFO)->SetWindowText(_T("文件接收完畢!rn"));
??????????? AfxMessageBox(_T("文件接收完畢!"));//醒目可以注釋
??????? }else
??????? {
??????????? AfxMessageBox(_T("獲取文件總大小失敗!"));
??????? }
??? }else
??? {
??????? AfxMessageBox(_T("連接服務(wù)器失敗、請(qǐng)確認(rèn)IP地址或端口號(hào)!"));
??? }
???
???

??? closesocket(sockClient);//關(guān)閉套接字


}

void CRecvFileClientDlg::ConnectServer()
{
??? if (InitSocket())
??? {
??????? DWORD strIp =NULL;
??????? CString strPort = _T("");

??????? ((CIPAddressCtrl*)GetDlgItem(IDC_IP))->GetAddress(strIp);
??????? GetDlgItem(IDC_PORT)->GetWindowText(strPort);

??????? if (strIp==NULL||strPort=="")
??????? {
??????????? AfxMessageBox(_T("Ip地址或Port端口號(hào)不能為空!"));

??????? }else
??????? {
??????????? int port = atoi(strPort.GetBuffer(1));
??????????? ConnectRecvFileData(strIp,port);
???????????
??????? }
???????
??? }
???

}

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉