在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
原代码链接如下:
http://download.csdn.net/download/thecentry/10188777