1. 程式人生 > >TCP檔案傳輸MFC伺服器篇

TCP檔案傳輸MFC伺服器篇

在VS2015下用對話方塊實現的網路檔案傳輸,介面如下

開啟伺服器要實現的功能是:

1:載入socket庫

2:建立socket

3:繫結伺服器IP和埠

4:監聽客服端的連線

5:設定非同步套接字

開啟伺服器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"));
}
為了防止多次開啟伺服器操作,我這裡一旦開啟了伺服器就把button設定為不可按了。

這裡面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
原始碼連結如下: