亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? server1.cpp

?? 一個簡單的視頻會議VC++MFC工程文件
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
// server1.cpp : Defines the class behaviors for the application.
//作者:趙明
//EMAIL:zmpapaya@hotmail.com;papaya_zm@sina.com
//主頁:http://h2osky.126.com

#include "stdafx.h"
#include "server1.h"
#include "mysocket.h"
#include "MainFrm.h"
#include "server1Doc.h"
#include "server1View.h"
#include "linkctrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CServer1App
#define SIZE                            20480
BEGIN_MESSAGE_MAP(CServer1App, CWinApp)
	//{{AFX_MSG_MAP(CServer1App)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CServer1App construction

CServer1App::CServer1App()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CServer1App object
DWORD WINAPI clientthread(LPVOID lpparam);
//二維數組,第一維是10,對應于是個數組元素,第二維是一個字符串。
//這個二維數組是用來存儲加到List控件中的各個文件的全路徑用的。
char nameph[10][255];
 
CServer1App theApp;

//文件信息
struct fileinfo
{
	int fileno;//文件號
	int type;//消息類別。有兩種有效的取值:0和2 //客戶端想說什么(前面那兩句話,用1,2表示)
	long len;//文件長度
	int seek;//開始位置
	char name[100];//文件名
};

int sendn(SOCKET fd,char *bp,int len);


//應該參照Visual C++實踐與提高系列叢書-網絡編程篇-配套源碼-第8章的內容,看看監聽線程
//到底應該怎么設計才對。
//監聽函數,這是一個線程函數。其實,我覺得不應該稱此函數所對應的線程為“監聽線程”,因為監聽
//只是一個設置的過程,調用listen函數,監聽過程就開始了。應該稱其為“循環等待連接線程”更好。
DWORD WINAPI listenthread(LPVOID lpparam)
{	
	//參數lpparam指向的是一個socket,這個socket是用來監聽客戶端的連接請求用的。
	SOCKET  sListening=(SOCKET)lpparam;
	//用傳遞進來的參數所指向的socket進行監聽,允許接受的最大連接數是30。
	//The listen function places a socket a state where it is listening for an incoming connection.
	//Return Values  If no error occurs, listen returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
	//這個函數調用不會發生阻塞,只有accept函數調用才會阻塞。
	int rc=listen(sListening,30);

	if(rc==SOCKET_ERROR)
	{
		CString aaa;
		aaa="listen錯誤\n";
		AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aaa.GetBuffer(0),1);
		aaa.ReleaseBuffer();
		return 0;
	}

	//用下面的這個死循環來不斷接收來自客戶端的連接請求。對于每一個連接socket,都為其啟動一個
	//單獨的線程,需要注意的是:其線程函數是clientthread,而并不是本監聽線程函數。
	//我感覺下面的代碼好像有問題呀,怎么退出這個死循環呢,這樣,此線程豈不是死掉了嗎?
	//應該參照Visual C++實踐與提高系列叢書-網絡編程篇-第8章的內容,看看等待連接的線程到底應該怎么設計才對。
	while(1)
	{
		//sConnect是一個局部變量。需要注意的是:雖然此變量是一個局部變量,但是,此變量所指向的
		//新創建的socket卻并不是一個局部的對象,除非你調用closesocket函數關閉它,否則它會
		//一直存在,直至進程結束。
		//經過考證,發現SOCKET原來就是UINT_PTR數據類型,這是一個無符號指針類型。
		//有一個問題,在while循環中,反復執行下面這句代碼,會產生出多個局部的sConnect變量嗎?
		//可以做一個試驗程序測試一下。
		//答:經過測試,發現并沒有在每一次循環的時候都產生出一個新的局部變量來,而是始終都
		//只有一個局部變量sConnect,此變量的地址始終不變。
		SOCKET sConnect;

		//第一個參數:[in] Descriptor identifying a socket that has been placed in a listening state with the listen function. The connection is actually made with the socket that is returned by accept. 
		//返回值:If no error occurs, accept returns a value of type SOCKET that is a descriptor for the new socket. This returned value is a handle for the socket on which the actual connection is made.
		//流程執行到這里,將會阻塞,如果沒有客戶端的連接請求發來。
		sConnect=accept(sListening,NULL,NULL);

		if(sConnect==INVALID_SOCKET)
		{
			//經過我的測試發現,當我調用closesocket函數關閉監聽socket的時候,流程會執行到
			//這里面來。但是,由于進程會接著被中斷,所以,Message Box只是一閃就被關閉了,或者
			//是根本連閃一下都沒有,進程就結束了。
			char szTemp[10];
			sprintf(szTemp,"123456789 ErrorCode=%d",WSAGetLastError());
			::MessageBox(NULL,szTemp,"",0);
//			continue;
			return -1;//這樣設計對嗎,我不敢確定?
		}

		CString aa;
		aa="一人聯入!\n";
		//這是一個mfc函數,Call this member function to send the specified Windows message to all descendant windows.
		//在本程序中的作用是:把串aa的內容,在RichEdit控件中顯示出來。
		AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
		aa.ReleaseBuffer();

		DWORD dwThread;
		//在這里創建了一個新的線程,但是要注意的是,這一次的線程函數變了,變成了clientthread,
		//這個線程是用來處理客戶端的連接用的線程。
		//在“VC 實踐與提高 網絡編程篇”的第8章的例子中,采用的是線程套線程的設計方法,
		//我個人感覺,這種層層嵌套的設計方法好像不太好,還不如這種死循環的設計方法更好呢,
		//不知我的感覺是否正確,有誰能告訴我理論依據是什么??????
		::CreateThread(NULL,0,clientthread,(LPVOID)sConnect,0,&dwThread);	
	}

	return 0;
}

//從客戶端讀取數據的函數。
//參數1:連接套接字;參數2:指向緩沖區的指針;參數3:緩沖區的長度;
int readn(SOCKET fd,char *bp,int len)
{
	int cnt;//用來記錄緩沖區中的剩余可用空間。
	int rc;
	cnt=len;
	while(cnt>0)
	{
		//Platform SDK: Windows Sockets  The recv function receives data from a connected or bound socket.
		//Return Values  If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
		//cnt參數的值被設定為緩沖區的長度值,所以,在網絡速度足夠好的情況下,讀取cnt這么
		//多的字節,沒問題。這樣的話,此while循環只需要執行一次就會正常退出了。從而,我也
		//明白了while循環的作用,就是:用來保證一定要讀取cnt這么多的字節,讀不夠數就
		//反復地讀,直至讀夠數了,或者是此連接被關閉掉了。
		//我有一個疑問:如果客戶端只發過來50個字節的數據,會怎么樣呢?其實,這個問題,只需要查到合適的資料,就可以輕松解決,并無任何的難度可言。
		//答:??????
		rc=recv(fd,bp,cnt,0);

		if(rc==SOCKET_ERROR)
		{
			CString aa;
			aa="接收錯誤!\n";
			AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
			aa.ReleaseBuffer();
			return -1;
		}

		//If the connection has been gracefully closed, the return value is zero.
		if(rc==0) 
			return len-cnt;
		//讀取了一些數據之后,緩沖區指針也應該相應地增加。
		bp+=rc;
		//讀取了一些數據之后,緩沖區中的剩余可用空間也應該相應地減小。
		cnt-=rc;
	}
	return len;
}

filesendinfo zmfile[10];//記錄文件,這是一個結構體數組。
#define SIZE_OF_zmfile 1080

//向客戶端發送數據的函數。
//參數1:連接socket;參數2:緩沖區指針;參數3:要發送的字節數,其實就是緩沖區中的數據數;
int sendn(SOCKET fd,char *bp,int len)
{
	int cnt;
	int rc;
	cnt=len;
	//我覺得,之所以需要用一個while循環來發送數據,大概是因為send函數也許不能把指定數量數據
	//一次都發送完吧,所以需要用一個循環來反復地發送,直至所有的數據都發送完,或者是出錯。
	while(cnt>0)
	{
		//send  The send function sends data on a connected socket.
		//send函數的返回值可用來表示已經成功地發送出去了多少數據,至于客戶端能否成功地收到
		//這些數據,好像并不能在send函數的返回值中體現出來。其實,能否成功地收到數據是客戶端
		//的事,跟服務器端無關。也許數據被客戶端的防火墻攔截了,這樣,客戶端就永遠也不能收到
		//這些數據了,不過,這些亂七八糟的事,服務器端可管不著。
		rc=send(fd,bp,cnt,0);
		if(rc==SOCKET_ERROR)
		{
			CString aa;
			aa="發送錯誤!\n";
			AfxGetMainWnd()->SendMessageToDescendants(WM_AGE1,(LPARAM)aa.GetBuffer(0),1);
			aa.ReleaseBuffer();
			return -1;
		}
		if(rc==0)
			return len-cnt;
		//發送完了一批數據后,緩沖區指針當然要向后移了。如果指定數量的數據已經發送完了,則
		//bp就指向緩沖區的末尾了。
		bp+=rc;
		//發送完了一批數據,則cnt(用來記錄還沒發送完的數據)的數值當然需要減去已經發送了的了。
		cnt-=rc;
	}
	return len;
}

//讀文件的函數,這個函數大概就是傳送文件的具體函數吧。
//實現多線程下載和斷點續傳的前提條件就是:服務器端要支持隨機存取文件。這就要求傳遞一個
//seek變量,因為需要用這個seek變量尋找到上次的斷點或者是把文件分成幾段分別下載。
//參數1:連接socket;參數2:隨機存取文件用的的定位指針;參數3:此次下載操作要從文件中讀取的字節數;參數4:服務器設定的可供下載的文件列表中的文件的編號(編號是從0開始的),用作nameph數組的下標;
void readfile( SOCKET so , int seek , int len , int fino )
{
	//文件名全路徑。
	CString myname;
	//將要下載的文件的全路徑賦值給myname串。
	myname.Format("%s",nameph[fino]);
	CFile myFile;
	//打開文件。為了支持多線程下載,必須要以共享的方式打開文件才行!
	myFile.Open( myname, CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone ); 

	//定位到指定位置
	//CFile::Seek  The Seek function permits random access to a file's contents by moving the pointer a specified amount, absolutely or relatively. No data is actually read during the seek. If the requested position is larger than the size of the file, the file length will be extended to that position, and no exception will be thrown.
	//When a file is opened, the file pointer is positioned at offset 0, the beginning of the file.
	//CFile::begin   Move the file pointer lOff bytes forward from the beginning of the file. 
	myFile.Seek(seek,CFile::begin);
	//這是一個用來從文件中讀取數據,然后再發送的緩沖區。
	char m_buf[SIZE];
	int len2;

	//開始向客戶端發送,指定文件中的,指定位置處的,指定數量的,數據。
	//之所以需要使用while循環來發送數據,是因為每一次最多只能發送SIZE這么多的數據,所以,有
	//可能需要進行多次的發送,這就需要用到循環了。
	while(len>0)
	{
		//每一次發送的數據量,不能超過m_buf這個緩沖區的最大尺寸。如果客戶所要求的數據量小于
		//緩沖區的尺寸,就只需要讀取len這么多的數據就行了。
		len2=len>SIZE?SIZE:len;
		myFile.Read(m_buf, len2);
		//向客戶端發送數據。
		int aa=sendn(so,m_buf,len2);
		//如果發送過程出現錯誤,則
		if(aa<0)
		{	
			closesocket (so);
			break;
		}
		//對,發送完了一批數據后,就應該從總數中把“已經發送完了的那些數據的數量”減去。
		len=len-aa;
	}
	//對,用完了文件之后,需要關閉它。
	myFile.Close();
}

//“用來處理服務器與客戶端的一次連接用的線程”的線程函數。
//其參數是:連接用的socket。
DWORD WINAPI clientthread(LPVOID lpparam)
{
	//文件消息
	fileinfo* fiinfo;
	//接收緩存

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美性色综合网| 久久久久久久久免费| 亚洲一区二区在线视频| 国产在线国偷精品产拍免费yy| 一本在线高清不卡dvd| 中文字幕精品在线不卡| 高清视频一区二区| 久久久亚洲国产美女国产盗摄 | 久久久久国产精品厨房| 国内成人免费视频| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 国产一区二区视频在线| 久久综合色播五月| 国产91精品在线观看| 亚洲欧洲精品天堂一级| 99久久99久久精品免费看蜜桃| 国产精品久久久久7777按摩| 91啪亚洲精品| 午夜激情一区二区三区| 日韩免费电影一区| 国产精品一区二区在线观看网站 | 色天天综合久久久久综合片| 中文字幕+乱码+中文字幕一区| av欧美精品.com| 亚洲18色成人| **性色生活片久久毛片| 欧美日高清视频| 成人黄色网址在线观看| 亚洲国产精品久久不卡毛片| 国产人成亚洲第一网站在线播放| 欧美中文一区二区三区| 国产精品1区二区.| 日韩电影在线免费| 亚洲精品写真福利| 中文字幕不卡的av| 精品少妇一区二区三区视频免付费| 日韩一区二区三区三四区视频在线观看| 欧美精品一区二区蜜臀亚洲| 韩国三级在线一区| 国产综合色视频| 91在线国内视频| 欧美日韩午夜在线视频| 日韩你懂的在线观看| 国产精品沙发午睡系列990531| 亚洲视频中文字幕| 久久精品国产99国产| av午夜一区麻豆| 欧美电视剧在线观看完整版| 欧美国产欧美综合| 中文字幕电影一区| 亚洲免费看黄网站| 依依成人精品视频| 亚洲一区二区中文在线| 美女www一区二区| 国内精品久久久久影院一蜜桃| 国产精品资源网| eeuss鲁片一区二区三区在线观看| 成人污污视频在线观看| av在线一区二区三区| 在线看国产一区| 欧美一区二区三区在线| 国产午夜精品久久| 亚洲欧美国产三级| 午夜久久电影网| 狠狠色综合日日| 91美女片黄在线| 日韩精品专区在线| 自拍偷在线精品自拍偷无码专区| 亚洲精品高清视频在线观看| 免费在线观看精品| 99九九99九九九视频精品| 欧美日韩电影一区| 最新日韩在线视频| 美女mm1313爽爽久久久蜜臀| 91麻豆免费看片| 精品少妇一区二区三区在线播放| 一区二区三区中文字幕在线观看| 狠狠色综合播放一区二区| 欧美无砖专区一中文字| 中文字幕在线不卡| 国产综合色精品一区二区三区| 欧美日韩免费在线视频| 国产精品久久久久久久久久久免费看 | 久久久精品国产99久久精品芒果| 亚洲综合免费观看高清完整版在线 | 成人动漫一区二区在线| 日韩精品最新网址| 亚洲精品福利视频网站| 成人免费不卡视频| 亚洲精品一区二区三区在线观看| 亚洲在线成人精品| 色网站国产精品| 中文字幕一区二区三区不卡| 国产一区二区伦理片| 日韩亚洲欧美成人一区| 蜜臀av亚洲一区中文字幕| 欧美日韩免费在线视频| 一区二区三区小说| 色哟哟国产精品| 五月婷婷综合在线| 91精品国产福利在线观看| 蜜桃视频免费观看一区| 日韩一区二区免费在线观看| 久久99国产精品尤物| 久久精品人人做人人综合 | 国产毛片精品国产一区二区三区| 日韩欧美一二三| 精品一二三四区| 国产精品麻豆久久久| 日本电影亚洲天堂一区| 亚洲r级在线视频| 精品成a人在线观看| 91视视频在线观看入口直接观看www | 欧美国产日韩在线观看| 欧美午夜电影在线播放| 激情成人综合网| 一区二区久久久| 久久噜噜亚洲综合| 欧美在线观看禁18| 韩国欧美一区二区| 日本怡春院一区二区| 亚洲视频狠狠干| 国产日韩高清在线| 精品欧美久久久| 欧美一三区三区四区免费在线看| 色婷婷激情久久| 91无套直看片红桃| 北条麻妃一区二区三区| 国产一区三区三区| 国产一区二区在线电影| 韩国精品一区二区| 欧美电影在线免费观看| 日韩一区日韩二区| 亚洲三级在线观看| 欧美mv和日韩mv的网站| 欧美一区二区三区小说| 日韩一区二区在线看| 亚洲国产精品国自产拍av| 日韩国产精品91| 国产成人免费av在线| 成人免费观看视频| 欧美性视频一区二区三区| 337p亚洲精品色噜噜狠狠| 精品奇米国产一区二区三区| 中文字幕成人网| 丝袜亚洲另类欧美| 成人午夜av在线| 欧美精品三级在线观看| 国产精品人成在线观看免费| 亚洲成人综合视频| 国产91精品一区二区麻豆亚洲| 欧美日韩一级二级| 国产精品护士白丝一区av| 日本亚洲最大的色成网站www| bt欧美亚洲午夜电影天堂| 日韩午夜中文字幕| 亚洲激情欧美激情| 成人性生交大片| 精品国产伦一区二区三区观看方式| 一区二区三区成人在线视频| 国产91清纯白嫩初高中在线观看| 欧美人妇做爰xxxⅹ性高电影 | 国产精品免费网站在线观看| 久久97超碰国产精品超碰| 欧美日韩高清一区| 亚洲国产视频一区二区| 色妞www精品视频| 日韩美女啊v在线免费观看| 九色porny丨国产精品| 欧美精品黑人性xxxx| 亚洲r级在线视频| 91精品欧美一区二区三区综合在| 亚洲黄色av一区| 色999日韩国产欧美一区二区| 欧美极品美女视频| 不卡的av中国片| 亚洲卡通欧美制服中文| 色综合av在线| 亚洲超碰97人人做人人爱| 在线播放亚洲一区| 日韩高清在线电影| 欧美tickling网站挠脚心| 国产一区二区网址| 亚洲视频在线一区观看| 欧美午夜一区二区三区免费大片| 久久国产精品免费| 国产亚洲一区二区三区四区| 成人av在线网站| 亚洲第一二三四区| 日韩欧美成人一区二区| 国产成人免费9x9x人网站视频| 国产精品美女久久久久久久| 91九色02白丝porn| 国产一区中文字幕| 亚洲日本欧美天堂| 欧美一区二区不卡视频| 国产一区 二区 三区一级| 亚洲精品久久久久久国产精华液| 欧美一区二区三区在线| av亚洲精华国产精华精|