佛山网站建设 天博,淮安市建设局网站首页,百度seo招聘,曹鹏的wordpress教程首先是服务器端#xff0c;大致说下流程#xff1a;服务器创建线程去处理应答accept()#xff0c;当接受到客户端连接请求时#xff0c;首先获取要发送的指定的文件数据总大小给客户端#xff0c;接着就是循环读取要发送的文件数据流向客户端发送文件数据#xff0c;每次… 首先是服务器端大致说下流程服务器创建线程去处理应答accept()当接受到客户端连接请求时首先获取要发送的指定的文件数据总大小给客户端接着就是循环读取要发送的文件数据流向客户端发送文件数据每次都判断循环读取到的数据实际大小当实际读取到的数据总大小为0时表示文件发送结束。下面是服务器server端实现 声明部分 public:afx_msg void OnBnClickedButton1();
public:BOOL InitSocket(); //初始化并创建套接字static DWORD WINAPI ThreadProc(LPVOID lpParameter); //创建线程去执行服务器accept() 实现部分 void CSendFileServerDlg::OnBnClickedButton1()
{// TODO: 在此添加控件通知处理程序代码if (InitSocket()){GetDlgItem(IDC_EDIT1)-SetWindowText(_T(服务器开启监听。。。 \r\n));//创建线程HANDLE hThread CreateThread(NULL,0,ThreadProc,NULL,0,NULL);//关闭该接收线程句柄释放引用计数CloseHandle(hThread);}
}BOOL CSendFileServerDlg::InitSocket()
{//加载套接字库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;}//创建套接字//SOCKET m_socketsocket(AF_INET,SOCK_STREAM,0);m_socketsocket(AF_INET,SOCK_STREAM,0);if (m_socket INVALID_SOCKET){AfxMessageBox(_T(套接字创建失败));return FALSE;}SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addrhtonl(INADDR_ANY);addrSrv.sin_familyAF_INET;addrSrv.sin_porthtons(8099);err bind(m_socket,(SOCKADDR*)addrSrv,sizeof(SOCKADDR)); //绑定本地端口if (errSOCKET_ERROR){closesocket(m_socket);AfxMessageBox(_T(绑定失败));return FALSE;}listen(m_socket,5);//开启监听return TRUE;}DWORD WINAPI CSendFileServerDlg::ThreadProc(LPVOID lpParameter)
{SOCKADDR_IN addrClient;int len sizeof(SOCKADDR);while (true){SOCKET sockConnaccept(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;
} 如代码所述 每次发送单位是unsigned char[1024]大小(程序是char 应该为unsigned char[1024])所以就不存在网络字节序问题也不用考虑大端小端什么的。 服务器端暂时不支持多客户端并发访问后续可能会加上。。。 ------------------------------------------- 下面是客户端同样也大致说下客户端流程客户端增加手动填写Ip地址和端口号功能(端口号暂为8099)。以及下载传输文件数据进度条的显示和下面简单的一些状态显示。客观端由填写的IP地址进行连接服务器操作如果客户端连接服务器成功的话直接就会获取服务器端发送的要发送的文件数据的总大小如果获取文件总大小0 则会循环往指定的路径写数据啦。此处循环写文件结束标志我是用每次实际写的累加如果累计值等于从服务器端获取的文件总大小的话表示下载文件数据成功结束循环。大致是这样一个过程。代码实现 客户端声明部分 public: afx_msg void OnBnClickedButton1(); BOOL InitSocket(); void ConnectServer(); void ConnectRecvFileData(DWORD ip,int port); private: CProgressCtrl *m_progress; //进度条 进度条在OnInitDialog()里初始化 BOOL CRecvFileClientDlg::OnInitDialog()
{CDialog::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。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);}}// 设置此对话框的图标。当应用程序主窗口不是对话框时框架将自动// 执行此操作SetIcon(m_hIcon, TRUE); // 设置大图标SetIcon(m_hIcon, FALSE); // 设置小图标// TODO: 在此添加额外的初始化代码
m_progress (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1); m_progress-SetPos(0); return TRUE; // 除非将焦点设置到控件否则返回 TRUE
} 客户端具体实现部分 void CRecvFileClientDlg::OnBnClickedButton1()
{// TODO: 在此添加控件通知处理程序代码ConnectServer();}BOOL CRecvFileClientDlg::InitSocket()
{//加载套接字库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_size0;SOCKET sockClient socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addrhtonl(ip);addrSrv.sin_portntohs(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(连接服务器成功\r\n));recv(sockClient,(char*)file_size,sizeof(unsigned long long)1,NULL);unsigned short maxvalue file_size; //此处不太稳妥 当数据很大时可能会出现异常m_progress-SetRange(0,maxvalue); if (file_size0){ GetDlgItem(IDC_SHOWINFO)-SetWindowText(_T());GetDlgItem(IDC_SHOWINFO)-SetWindowText(_T(文件下载到本地 d\\test.zip \r\n));DWORD dwNumberOfBytesRecv0;DWORD dwCountOfBytesRecv0;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);//更新进度条
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(文件接收完毕\r\n));AfxMessageBox(_T(文件接收完毕!));//醒目可以注释}else{AfxMessageBox(_T(获取文件总大小失败));}}else{AfxMessageBox(_T(连接服务器失败、请确认IP地址或端口号));}closesocket(sockClient);//关闭套接字
}void CRecvFileClientDlg::ConnectServer()
{if (InitSocket()){DWORD strIp NULL;CString strPort _T();((CIPAddressCtrl*)GetDlgItem(IDC_IP))-GetAddress(strIp);GetDlgItem(IDC_PORT)-GetWindowText(strPort);if (strIpNULL||strPort){AfxMessageBox(_T(Ip地址或Port端口号不能为空));}else{int port atoi(strPort.GetBuffer(1));ConnectRecvFileData(strIp,port);}}}