#pragma once
#include <afxsock.h>
#define WM_FILELIST WM_USER + 101 //接收文件列表
#define WM_FILEUPDATE WM_USER + 102 //反映文件下载状态
#define WM_FILEDOWNLOAD WM_USER + 103 //发送文件列表
#define FILELIST 1000 //请求文件列表
#define FILEUPDATE 2000 //请求文件上传
#define FILEDOWNLOAD 3000 //请求文件下载
#define RECVSIZE 1024*16 //一次性发送/接收的数据块大小
//与服务器通信语言结构
typedef struct
{
int iCommand;
long lFileOffset;
long lFileLength;
char sFilePath[128];
}MSGFILE;
//请求线程参数
typedef struct
{
char sIP[15]; //IP地址
int iPort; //端口
MSGFILE msgFile; //通信语言结构
LPVOID ptr; //指针
}MSGPARAM;
//文件列表结构
typedef struct
{
long lFileLength;
char sFilePath[128];
}MSGFILELIST;
//反映文件状态的结构
typedef struct
{
long lFileOffset;//偏移
char sFilePath[128];//路径
}MSGFILESTATUS;
//接收线程参数
typedef struct
{
SOCKET sock;
LPVOID ptr;
}PARAMRECV;
//服务器端 类 头文件
// Ftp_Server.h: interface for the CFtp_Server class.
//
//
#if !defined(AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_)
#define AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "basedef.h"
#define WM_FINISHUPDATE WM_USER+401
class CFtp_Server
{
public:
CFtp_Server();
virtual ~CFtp_Server();
BOOL StartListen(CWnd *pWnd, int nPort, char *sPath);
void StopListen();
protected:
//监听线程
static DWORD WINAPI ListenThread(LPVOID lpParam);
//接收线程
static DWORD WINAPI RecvThread(LPVOID lpParam);
private:
//监听线程结束符
BOOL m_bEndListenThread;
//监听端口
int m_iListenPort;
//窗口指针
CWnd* m_pWnd;
//服务器套接字
SOCKET m_socket;
//保存本机地址
SOCKADDR_IN m_sin;
//存储路径
char m_sPath[128];
};
#endif // !defined(AFX_FTP_SERVER_H__DCFE7BE8_C212_475E_AAC8_811898047B46__INCLUDED_)
//服务器端 类 CPP
// Ftp_Server.cpp: implementation of the CFtp_Server class.
//
//
#include "stdafx.h"
#include "Ftp_Server.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
//
// Construction/Destruction
//
CFtp_Server::CFtp_Server()
{
}
CFtp_Server::~CFtp_Server()
{
}
BOOL CFtp_Server::StartListen(CWnd *pWnd, int nPort, char *sPath)
{
//初始化套接字
if (!AfxSocketInit())
{
return FALSE;
}
//获得端口号和窗口指针
m_iListenPort = nPort;
m_pWnd = pWnd;
strcpy(m_sPath, sPath);
m_bEndListenThread = FALSE;//开始监听
DWORD id;
HANDLE h = CreateThread(NULL, 0, ListenThread, this, 0, &id);//创建句柄
//线程要执行的函数为ThreadListen,将this指针传递给线程,线程ID为id,创建成功,返回新线程的一个句柄
CloseHandle(h); //关闭句柄,并不终止线程
return TRUE;
}
void CFtp_Server::StopListen()
{
m_bEndListenThread = TRUE;
Sleep(100);
closesocket(m_socket);
}
DWORD WINAPI CFtp_Server::ListenThread(LPVOID lpParam)
{
CFtp_Server* pServer = (CFtp_Server*)lpParam;
SOCKET sockListen = socket(AF_INET, SOCK_STREAM, 0);//创建socket
//地址家族为internet,用于TCP和UDP,字节流,特定的协议
SOCKADDR_IN sin; //转换地址
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0; //ip地址,以网路字节顺序。
sin.sin_port = htons(pServer->m_iListenPort);
if (bind(sockListen, (SOCKADDR*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
closesocket(sockListen); //关闭socket
return FALSE;
}
if (listen(sockListen, 5) == SOCKET_ERROR)
{//若将socket置于监听失败
closesocket(sockListen);
return FALSE;
}
fd_set fdListen;//结构体,将socket放进一个集合
timeval seltime;//结构体,指定时间值(秒+毫秒)
seltime.tv_sec = 0; //秒
seltime.tv_use