?? server1.cpp
字號:
char* m_buf;
m_buf=new char[100];
SOCKET sConnect1=(SOCKET)lpparam;
//調用自定義的函數,從客戶端讀取100字節的數據。
int aa=readn(sConnect1,m_buf,100);
//如果讀取數據的時候發生了錯誤,則
if(aa<0)
{
//關閉此連接用的socket。
closesocket(sConnect1);
return -1;
}
//強制的數據類型轉換,把傳來的信息轉為定義的文件信息
fiinfo=(fileinfo*)m_buf;
CString temp;
temp.Format("re %d from there",aa);
CString aaa;
//用來面的這個switch代碼塊,來檢驗客戶想說什么
switch(fiinfo->type)
{
//type==0,大概表示:客戶端需要從服務器端讀取可以下載的文件列表的信息。
case 0:
//向客戶端發送1080字節(就是10個數組元素)的數據,
//zmfile這個結構體數組中存放的是:服務器端程序中可供用戶端下載的文件的信息
//(文件名、文件的長度)。
//每一個zmfile數組元素的大小是108個字節,所以,10個元素就一共是1080個字節。
//其實,這種直接寫上一個數字的編程方法并不好,因為如果以后結構體的設計變了,那么
//這種硬性寫上的數字就需要重新改寫,而且,如果在多處都用到這個數字,那么改寫起來
//就非常的麻煩。正確的寫法是:用上sizeof,或者,最起碼要用上一個宏定義,這樣,
//只需要改寫宏的數值就行了。
aa=sendn(sConnect1,(char*)zmfile,SIZE_OF_zmfile);
//added for test begin
// char stemp[35];
// sprintf(stemp,"SIZE_OF_zmfile=%d \n",SIZE_OF_zmfile);
// AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)stemp,1);
//經過測試,發現SIZE_OF_zmfile的值的確是1080
//added for test end
//如果有錯,則
if(aa<0)
{
closesocket (sConnect1);
return -1;
}
//發消息給主窗體,不過,我發現處理此消息的函數卻在視類中,難道是mfc的消息傳遞機制
//把消息轉送給視類了嗎?
//答:我估計,一定是這么回事。
aaa="收到LIST命令\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
break;
//type==2,大概表示:客戶端準備好了,所以你(指服務器)可以開始傳送文件了。
case 2:
//“XX.xxx 文件被請求! 文件的全路徑”。一個例子是:TDA7293.pdf 文件被請求!C:\Documents and Settings\YJK\My Documents\TDA7293.pdf
aaa.Format("%s 文件被請求!%s\n",zmfile[fiinfo->fileno].name,nameph[fiinfo->fileno]);
//將客戶端要下載的文件的信息,顯示到RichEdit控件中。
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
//這個函數大概就是傳送文件的具體函數吧。
readfile(sConnect1,fiinfo->seek,fiinfo->len,fiinfo->fileno);
break;
//服務器端無法理解客戶端的需求,因為當前服務器端只能理解type==0和type==2的這兩種請求。
default:
aaa="接收協議錯誤!\n";
AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CServer1App initialization
BOOL CServer1App::InitInstance()
{
//在下面的這個函數中,調用了WSAStartup函數初始化了WinSock。至于對應的WSACleanup函數,
//也許不必調用了吧。因為由AppWizard自動生成的支持WinSock的程序框架中,根本就沒有
//對WSACleanup函數的調用。
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CServer1Doc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CServer1View));
pDocTemplate->SetContainerInfo(IDR_CNTR_INPLACE);
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
//added by author begin
//Centers a window relative to its parent.If the pop-up window is not owned, it is centered relative to the screen.
m_pMainWnd->MoveWindow(0,0,800,600,true);
//我試過了,下面這一句的確管用。
m_pMainWnd->CenterWindow();
m_pMainWnd->SetWindowText("月影傳書");
m_pMainWnd->ShowWindow(SW_SHOW); //這句代碼不是作者添加了,是AppWizard自動生成的。
m_pMainWnd->UpdateWindow(); //這句代碼不是作者添加了,是AppWizard自動生成的。
// WORD wVersionRequested;//commented by me!
// WSADATA wsaData;//commented by me!
char name[255];
PHOSTENT hostinfo;
//WORD 16-bit unsigned integer.
//The MAKEWORD macro creates a WORD value by concatenating the specified values.
//用兩個8位的BYTE類型的數,合成一個16位的數。表示要使用 WinSock 2.0 版。
// wVersionRequested = MAKEWORD( 2, 0 );//commented by me!
//The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup.
//使用API版本的WinSock的時候,需要先調用此函數。
//Return Values The WSAStartup function returns zero if successful. Otherwise, it returns one of the error codes listed in the following.
//如果初始化WinSock成功,則
//經過思考,我認為下面的這一句代碼根本就是多余,因為在本函數中的開始處已經調用了if (!AfxSocketInit())
//這一句代碼,在AfxSocketInit函數內部已經調用了一次WSAStartup函數了。
// if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )//commented by me!
{
//The gethostname function returns the standard host name for the local machine.
if( gethostname ( name, sizeof(name)) == 0)
{
//The gethostbyname function retrieves host information corresponding to a host name from a host database.
//其參數是:[in] Pointer to the null-terminated name of the host to resolve.
//If retrieveing host information successfully, then
if((hostinfo = gethostbyname(name)) != NULL)
{
//The inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format.
/*
char FAR * inet_ntoa(
struct in_addr in
);
*/
//h_addr_list Null-terminated list of addresses for the host. Addresses are returned in network byte order. The macro h_addr is defined to be h_addr_list[0] for compatibility with older software.
//The in_addr structure represents a host by its Internet address.
/*
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
};
*/
//因為inet_ntoa函數的參數是in_addr類型的,所以,下面就用了這么復雜的數據類型轉換。
m_strIp = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
}
}
//The WSACleanup function terminates use of the Ws2_32.dll.An application or DLL is required to perform a successful WSAStartup call before it can use Windows Sockets services. When it has completed the use of Windows Sockets, the application or DLL must call WSACleanup to deregister itself from a Windows Sockets implementation and allow the implementation to free any resources allocated on behalf of the application or DLL.
//奇怪了,我覺得不應該在這里就調用WSACleanup函數呀,太早了呀,怎么回事呢?
//我覺得此函數應該放到App類的析構函數中調用才對。
//答:經過最新的分析,我認為下面的這一句根本就是多余。
// WSACleanup();//commented by me!
}
//added by author begin
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
CLinkCtrl m_mail;
CLinkCtrl m_http;
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual BOOL OnInitDialog();
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// afx_msg void OnButton1();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MAIL, m_mail);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// App command to run the dialog
void CServer1App::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CServer1App message handlers
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_mail.SetLinkString("http://www.sarahclub.com/");
m_http.SetLinkString("http://211.152.147.97/bbs/");
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -