TCP檔案傳輸MFC伺服器篇
阿新 • • 發佈:2019-02-09
在VS2015下用對話方塊實現的網路檔案傳輸,介面如下
開啟伺服器要實現的功能是:
1:載入socket庫
2:建立socket
3:繫結伺服器IP和埠
4:監聽客服端的連線
5:設定非同步套接字
開啟伺服器button的訊息響應如下:
為了防止多次開啟伺服器操作,我這裡一旦開啟了伺服器就把button設定為不可按了。void CFileServerDlg::OnStratrun() { // TODO: Add your control notification handler code here WORD ver = MAKEWORD(2, 0); WSADATA wsadata; if (WSAStartup(ver, &wsadata)) { MessageBox(_T("load winsock dll failing"), _T("load")); return; } //create socket socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == socket_server) { MessageBox(_T("create socket failing"), _T("create")); return; } //bind socket sockaddr_in addr_server; memset(&addr_server, 0, sizeof(sockaddr_in)); addr_server.sin_family = AF_INET; addr_server.sin_port = htons(10000); addr_server.sin_addr.S_un.S_addr = inet_addr("10.0.210.99"); if (bind(socket_server, (sockaddr*)&addr_server, sizeof(sockaddr))) { MessageBox(_T("bind ip failed"), _T("bind")); return; } //listen client listen(socket_server, 5); //set WSAAsyncSelect(socket_server, this->m_hWnd, WM_SOCKET, FD_ACCEPT);//wrong in here GetDlgItem(IDC_STRATRUN)->EnableWindow(false); // MessageBox(_T("successful open")); }
這裡面socket_server是定義的socket成員變數,WM_SOCKET是自定義的訊息響應。具體實現如下:
#pragma once
#define WM_SOCKET WM_USER+100
// CFileServerDlg dialog
class CFileServerDlg : public CDialogEx
protected:
HICON m_hIcon;
SOCKET socket_server;
SOCKET socket_client;
afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg LRESULT OnSocket(WPARAM wParam, LPARAM lParam); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP()
LRESULT CFileServerDlg::OnSocket(WPARAM wParam, LPARAM lParam) { if (LOWORD(lParam) == FD_ACCEPT) { //receive connect message sockaddr_in addr_client; memset(&addr_client, 0, sizeof(sockaddr_in)); int length_addr = sizeof(sockaddr_in); socket_client = accept(socket_server, (sockaddr*)&addr_client, &length_addr); MessageBox(_T("success in creating connection"), _T("connect")); return TRUE; } return FALSE; }
BEGIN_MESSAGE_MAP(CFileServerDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_STRATRUN, &CFileServerDlg::OnStratrun)
ON_MESSAGE(WM_SOCKET,OnSocket)
ON_BN_CLICKED(IDC_SENDFILE, &CFileServerDlg::OnSendfile)
ON_BN_CLICKED(IDC_RECVFILE, &CFileServerDlg::OnRecvfile)
ON_BN_CLICKED(IDCANCEL, &CFileServerDlg::OnBnClickedCancel)
END_MESSAGE_MAP()
接收檔案button訊息響應:
void CFileServerDlg::OnRecvfile()
{
// TODO: Add your control notification handler code here
//load to another file
CFileDialog recv_dlg(false);
if (IDOK == recv_dlg.DoModal())
{
CString file_path = recv_dlg.GetPathName();
//create file on the defined path
CFile file_recv(file_path, CFile::modeCreate | CFile::modeWrite);
//receive file
if (socket_client)
{
char recv_context[256]{ 0 };
while (SOCKET_ERROR!=recv(socket_client, recv_context, 256, NULL))
{
//write content
file_recv.Write(recv_context, sizeof(recv_context));
memset(recv_context, 0, 256);
}
}
//close file
file_recv.Close();
MessageBox(_T("receive successful"), _T("receive"));
}
}
傳送檔案button訊息響應:
void CFileServerDlg::OnSendfile()
{
// TODO: Add your control notification handler code here
//open file
CFileDialog send_dlg(TRUE);
if (IDOK == send_dlg.DoModal())
{
//get route
CString path_name = send_dlg.GetPathName();
//crete file
CFile file_context(path_name, CFile::modeRead);
char context[256]{ 0 };
//get content of file
while (file_context.Read(context, 255))
{
if (SOCKET_ERROR == send(socket_client, context, 255, NULL))
{
MessageBox(_T("send failed"), _T("send"));
return;
}
memset(context, 0, 256);
}
//close file
file_context.Close();
MessageBox(_T("send successful"), _T("send"));
}
}
退出button訊息響應:
void CFileServerDlg::OnBnClickedCancel()
{
// TODO: Add your control notification handler code here
closesocket(socket_server);//close server
closesocket(socket_client);//close client
WSACleanup();//unload socket
CDialogEx::OnCancel();
}
在編譯的過程中可能會出現一個問題,可能是這篇部落格提出解決方案的問題;點選開啟連結
http://blog.csdn.net/thecentry/article/details/78955431
原始碼連結如下: