當前位置:首頁 » 編程軟體 » socket編程mfc

socket編程mfc

發布時間: 2024-12-17 00:24:05

1. 基於mfc的socket編程怎麼進行文件傳輸

1. 採用了多線程的方法,文件傳輸時使用AfxBeginThread()開啟新線程

void CClientsockDlg::OnBnClickedSend()
{
pThreadSend = AfxBeginThread(Thread_Send,this);/
}

文件的發送和接收都開起了新線程

UINTThread_Send(LPVOID lpParam)
{
代碼略…
}

2. 支持從配置文件configuration.ini中獲取伺服器參數

採用GetPrivateProfileString()和GetPrivateProfileInt()分別獲取位於ServerConfiguration.ini文件中的String類型的IP和int類型的port
CString IP;
int port;
GetPrivateProfileString
(L"ServerConfiguration",L"IP",L"沒有讀取到數據!",IP.GetBuffer(10),10,L".\\configuration.ini");
port=GetPrivateProfileInt(L"ServerConfiguration",L"port",0,L".\\configuration.ini");

3. 採用了面向對象的設計方式,功能之間按模塊劃分
MFC本身具有良好的面向對象的特性,本程序嚴格按照MFC框架結構編寫代碼,每個按鈕對應一個功能函數,降低了代碼之間的耦合性,有利於程序的擴展和復用。

void CServersockDlg::OnBnClickedChoose()
void CServersockDlg::OnBnClickedSend()
void CServersockDlg::OnBnClickedRecvdata()
void CServersockDlg::OnBnClickedAbout()
void CServersockDlg::OnBnClickedWriteini()

4. 採用了CSocket類,代碼相對更簡單
CSocket類是MFC框架對socket編程中的winsockAPI的封裝,因此通過這個類管理收發數據更加便利。代碼也跟那個既簡單易懂。
//創建
if(!Clientsock.Socket())
{
CString str;
str.Format(_T("Socket創建失敗:%d"),GetLastError());
AfxMessageBox(str);
}
//連接
if(!Clientsock.Connect(IP,port))
{
CString str;
str.Format(_T("Socket連接失敗:%d"),GetLastError());
AfxMessageBox(str);
}
else
{
AfxMessageBox(_T("Socket連接成功"));
代碼略…
//發送
while(nSize<FindFileData.nFileSizeLow)
{
szBuff = new char[1024];
memset(szBuff,0x00,1024);
nSend =file.Read(szBuff,1024);
Clientsock.Send(szBuff,nSend);//發送數據
nSize += nSend;
}
file.Close();
delete szBuff;
Clientsock.Close();
(dlg->GetDlgItem(IDC_SEND))->EnableWindow(TRUE);
AfxMessageBox(_T("文件發送成功"));
dlg->SetDlgItemTextW(IDC_FILEPATHNAME,_T(""));
}
return 0;

5. 支持數據在伺服器與客戶端之間雙向傳輸

本程序不但可以從客戶端往伺服器端傳文件,而且可以從伺服器端往客戶端傳文件。
但是互傳文件的方式並不是完全相同的。
伺服器端不管是接收文件還是發送文件始終是對綁定的埠進行監聽。
//綁定
if(!Serversock.Bind(port))
{
CString str;
str.Format(_T("Socket綁定失敗: %d"),GetLastError());
AfxMessageBox(str);
}
//監聽
if(!Serversock.Listen(10))
{
CString str;
str.Format(_T("Socket監聽失敗:%d"),GetLastError());
AfxMessageBox(str);
}

客戶端不管是接收文件還是發送文件始終是進行連接。
if(!Clientsock.Connect(IP,port))
{
CString str;
str.Format(_T("Socket連接失ì敗:%d"),GetLastError());
AfxMessageBox(str);
}
else
{
略…

6. 完全圖形化操作界面

二.軟體使用說明

客戶端主界面如圖所示:

單擊「選擇文件」彈出文件對話框,選擇一個要發送的文件,同時保存文件的路徑。
單擊「發送」則會讀取ServerConfiguration.ini文件中的配置信息(IP和port),並根據此信息建立Socket連接,發送文件。注意:伺服器端應該先單擊了「接受客戶端數據」,否則發送失敗。
單擊「接收」也會讀取ServerConfiguration.ini文件中的配置信息(IP和port),並根據此信息建立Socket連接,接收文件。注意:伺服器端應該先選擇了向客戶端發送的文件,並單擊了「發送」,否則接受失敗。
單擊「讀取配置文件」,會從ServerConfiguration.ini文件中讀取配置信息,並以可編輯的文本形式顯示出來,修改完後,單擊「寫入配置文件」,會將修改後的信息保存到配置文件中。
單擊「關於」可以了解到軟體相關信息。
代碼注釋里有更詳細的說明

伺服器端主界面如圖所示

u 單擊「接受客戶端數據」,開始監聽客戶端的鏈接。
u 單擊「選擇文件」彈出文件對話框,選擇一個要發送的文件,同時保存文件的路徑。
u 單擊「發送」則會讀取ServerConfiguration.ini文件中的配置信息(port),並監聽對應埠,准備發送文件。注意:客戶端選擇「接收」以後才能發送成功。
u 單擊「讀取配置文件」,會從ServerConfiguration.ini文件中讀取配置信息,並以可編輯的文本形式顯示出來,修改完後,單擊「寫入配置文件」,會將修改後的信息保存到配置文件中。但是伺服器的IP是不可以修改的,它是在程序開始運行時從伺服器所在機器的網卡上獲取的。
u 單擊「關於」可以了解到軟體相關信息。
u 代碼注釋里有更詳細的說明

代碼下載地址:http://download.csdn.net/detail/leixiaohua1020/6320417

在此附上客戶端使用CSocket發起連接的代碼
[cpp] view plain
//----------------------------發送文件的線程------------------------------
UINT Thread_Send(LPVOID lpParam)
{
CClientsockDlg *dlg=(CClientsockDlg *)lpParam;
(dlg->GetDlgItem(IDC_SEND))->EnableWindow(FALSE);

CSocket Clientsock; //definition socket.
if(!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
}

CString IP;
int port;
GetPrivateProfileString(L"ServerConfiguration",L"IP",L"沒有讀取到數據!",IP.GetBuffer(100),100,L".\\configuration.ini");
port=GetPrivateProfileInt(L"ServerConfiguration",L"port",0,L".\\configuration.ini");
//創建
if(!Clientsock.Socket())
{
CString str;
str.Format(_T("Socket創建失敗: %d"),GetLastError());
AfxMessageBox(str);
}
//連接
// if(!Clientsock.Connect(_T("127.0.0.1"),8088))
if(!Clientsock.Connect(IP,port))
{
CString str;
str.Format(_T("Socket連接失敗: %d"),GetLastError());
AfxMessageBox(str);
}
else
{
AfxMessageBox(_T("Socket連接成功"));
WIN32_FIND_DATA FindFileData;
CString strPathName; //定義用來保存發送文件路徑的CString對象
dlg->GetDlgItemTextW(IDC_FILEPATHNAME,strPathName);
FindClose(FindFirstFile(strPathName,&FindFileData));
Clientsock.Send(&FindFileData,sizeof(WIN32_FIND_DATA));

CFile file;
if(!file.Open(strPathName,CFile::modeRead|CFile::typeBinary))
{
AfxMessageBox(_T("文件不存在"));
return 1;
}

UINT nSize = 0;
UINT nSend = 0;

char *szBuff=NULL;
//發送
while(nSize<FindFileData.nFileSizeLow)
{
szBuff = new char[1024];
memset(szBuff,0x00,1024);
nSend = file.Read(szBuff,1024);
Clientsock.Send(szBuff,nSend);//發送數據
nSize += nSend;
}
file.Close();
delete szBuff;
Clientsock.Close();
(dlg->GetDlgItem(IDC_SEND))->EnableWindow(TRUE);
AfxMessageBox(_T("文件發送成功"));
dlg->SetDlgItemTextW(IDC_FILEPATHNAME,_T(""));
}
return 0;
}

以及伺服器端使用CSocket監聽的代碼:
[cpp] view plain
//----------------------------監聽文件的線程------------------------------
UINT Thread_Func(LPVOID lpParam) //接收文件的線程函數
{
CServersockDlg *dlg = (CServersockDlg *)lpParam; //獲取對話框指針
(dlg->GetDlgItem(IDC_RECVDATA))->EnableWindow(FALSE);

if(!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
}

CString IP;
int port;
GetPrivateProfileString(L"ServerConfiguration",L"IP",L"沒有讀取到數據!",IP.GetBuffer(100),100,L".\\configuration.ini");
port=GetPrivateProfileInt(L"ServerConfiguration",L"port",0,L".\\configuration.ini");

char errBuf[100]={0};// 臨時緩存

SYSTEMTIME t; //系統時間結構

CFile logErrorfile;
if(!logErrorfile.Open(_T("logErrorfile.txt"),CFile::modeCreate|CFile::modeReadWrite))
{
return 1;
}

CSocket Serversock;
CSocket Clientsock;
//創建
if(!Serversock.Socket())
{
CString str;
str.Format(_T("Socket創建失敗: %d"),GetLastError());
AfxMessageBox(str);
}

BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
Serversock.SetSockOpt(SO_REUSEADDR,(void *)&bOptVal,bOptLen,SOL_SOCKET);

//綁定
if(!Serversock.Bind(port))
{
CString str;
str.Format(_T("Socket綁定失敗: %d"),GetLastError());
AfxMessageBox(str);
}
//監聽
if(!Serversock.Listen(10))
{
CString str;
str.Format(_T("Socket監聽失敗: %d"),GetLastError());
AfxMessageBox(str);
}

GetLocalTime(&t);
sprintf_s(errBuf,"伺服器已經啟動...正在等待接收文件...\r\n時間:%d年%d月%d日 %2d:%2d:%2d \r\n",t.wYear,t.wMonth,t.wDay,
t.wHour,t.wMinute,t.wSecond);
int len = strlen(errBuf);
logErrorfile.Write(errBuf,len);
AfxMessageBox(_T("啟動成功等待接收文件"));
while(1)
{
//AfxMessageBox(_T("伺服器啟動成功..."));
if(!Serversock.Accept(Clientsock)) //等待接收
{
continue;
}
else
{
WIN32_FIND_DATA FileInfo;
Clientsock.Receive(&FileInfo,sizeof(WIN32_FIND_DATA));

CFile file;
file.Open(FileInfo.cFileName,CFile::modeCreate|CFile::modeWrite);
//AfxMessageBox(FileInfo.cFileName);
int length = sizeof(FileInfo.cFileName);
logErrorfile.Write(FileInfo.cFileName,length);
//Receive文件的數據

UINT nSize = 0;
UINT nData = 0;

char *szBuff=NULL;

while(nSize<FileInfo.nFileSizeLow)
{
szBuff = new char[1024];
memset(szBuff,0x00,1024);
nData=Clientsock.Receive(szBuff,1024);
file.Write(szBuff,nData);
nSize+=nData;
}

delete szBuff;
Serversock.Close();
Clientsock.Close();
file.Close();
(dlg->GetDlgItem(IDC_RECVDATA))->EnableWindow(TRUE);
sprintf_s(errBuf,"文件接收成功...\r\n時間:%d年%d月%d日 %2d:%2d:%2d \r\n",t.wYear,t.wMonth,t.wDay,
t.wHour,t.wMinute,t.wSecond);
int len = strlen(errBuf);
logErrorfile.Write(errBuf,len);
//AfxMessageBox(_T("文件接收成功..."));
break;
}
}
return 0;
}

2. 一句MFC區域網即時通訊編程中的語句,不懂

構造方法摘要
Socket()
通過系統默認類型的 SocketImpl 創建未連接套接字
Socket(InetAddress address, int port)
創建一個流套接字並將其連接到指定 IP 地址的指定埠號。
Socket(InetAddress host, int port, boolean stream)
已過時。 Use DatagramSocket instead for UDP transport.
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
創建一個套接字並將其連接到指定遠程埠上的指定遠程地址。
Socket(Proxy proxy)
根據不管其他設置如何都應使用的指定代理類型(如果有),創建一個未連接的套接字。

熱點內容
墨泥加密鎖 發布:2025-03-12 02:15:40 瀏覽:340
我的世界網易開局就32k的伺服器 發布:2025-03-12 02:07:42 瀏覽:695
怎麼用電腦搭建免費伺服器 發布:2025-03-12 02:01:43 瀏覽:612
mysql存儲過程和函數 發布:2025-03-12 01:56:36 瀏覽:188
srt流媒體伺服器搭建 發布:2025-03-12 01:55:37 瀏覽:547
如何查找ftp電影下載資源 發布:2025-03-12 01:37:37 瀏覽:387
一加保存的密碼在哪裡 發布:2025-03-12 01:13:06 瀏覽:90
微信第三方平台源碼 發布:2025-03-12 01:12:21 瀏覽:782
伺服器關閉怎麼補償 發布:2025-03-12 01:01:26 瀏覽:335
c語言復數的四則運算 發布:2025-03-12 01:01:22 瀏覽:804