1、TCP/IP協議層次,各層協議?
答:應用層、傳輸層、網絡層、鏈路層;
1)應用層:FTP、Telnet、SMTP、HTTP、RIP、NFS、DNS
(2)傳輸層:傳輸控制協議TCP與用戶數據報協議UDP
(3)網際層協議:網際協議IP、網際控制報文協議ICMP、網際主機組管理協議IGMP、
(4)網絡接口層:地址解析協議ARP和RARP
2、在Internet中定位一個應用進程標識?(網間進程標識=傳輸協議+主機IP地址+端口號)
3、什麼是TCP,什麼是UDP,有什麼不同?
答:TCP:傳輸控制協議;是一種面向連接的、可靠的、基於字節流的運輸層通信協議。
UDP:用戶數據報協議;是一個簡單的面向數據報的傳輸層(transport layer)協議。
區別:UDP傳輸可靠性低,傳輸速度快,面向非連接,.;TCP傳輸可靠性高,傳輸速度慢,面向連接;
4、什麼是c/s模型?工作過程?
答:客戶-服務器模式;
工作過程:
首先服務器方要先啓動,並根據請示提供相應服務,過程如下:
(1)打開一通信通道並告知本地主機,它願意在某一個公認地址上接收客戶請求;
(2) 等待客戶請求到達該端口;
(3)服務器接收到服務請求,處理該請求併發送應答信號。爲了能併發地接收多個客戶的服務請求,要激活一個新進程或新線程來處理這個客戶請求,服務完成後,關閉此新進程與客戶的通信鏈路,並終止 ;
(4) 返回第二步,等待另一客戶請求;
(5) 關閉服務器。
客戶端:
1. 打開一通信通道,並連接到服務器所在主機的特定端口;
2. 向服務器發送服務請求報文,等待並接收應答;繼續提出請求……;
3. 請求結束後關閉通信通道並終止。
5、什麼是套接字?分類?什麼是數據報套接字,流試套接字?
答:通信的基礎,是支持網絡協議數據通信的基本接口;
分類: 流式套接字(SOCK_STREAM)是面向連接、可靠的、無差錯的傳輸服務,基於TCP;數據報套接字(SOCK_DGRAM)是面向無連接、不可靠、與數據包形式發送的傳輸服務,基於UDP;原始套接字是允許直接訪問較低層的 協議,基於ip,icmp。
6、基於TCP(流式套接字),UDP(數據包套接字)編程模式?
答:TCP模式:
服務器端程序:
1、創建套接字(socket)。
2、將套接字綁定到一個本地地址和端口上(bind)。
3、將套接字設爲監聽模式,準備接收客戶請求(listen)。
4、等待客戶請求到來;當請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept)。
5、用返回的套接字和客戶端進行通信(send/recv)。
6、返回,等待另一客戶請求。
7、關閉套接字。
客戶端程序:
1、創建套接字(socket)。
2、向服務器發出連接請求(connect)。
3、和服務器端進行通信(send/recv)。
4、關閉套接字。
UDP模式:
服務器端(接收端)程序:
1、創建套接字(socket)。
2、將套接字綁定到一個本地地址和端口上(bind)。
3、等待接收數據(recvfrom)。
4、關閉套接字。
客戶端(發送端)程序:
1、創建套接字(socket)。
2、向服務器發送數據(sendto)。
3、關閉套接字。
7、本機字節順序,網絡字節順序.
答:本機字節順序:不同的CPU有不同的字節序類型 這些字節序是指整數在內存中保存的順序 這個叫做主機序。
網絡字節順序:網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操作系統等無關,從而可以保證數據在不同主機之間傳輸時能夠被正確解釋。網絡字節順序採用big endian排序方式
8、基本操作函數.
答:啓動函數WSAStartup()和終止函數 WSACleanup()。
啓動函數WSAStartup():
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData );
wVersionRequested指Winsock的版本號(高字節指定副版本,低字節指定主版本)。Winsock 2.2表示爲0x0202;也可使用宏MAKEWORD(X,Y),X爲高位字節,Y爲低位字節,該宏創建一個被指定變量連接而成的WORD變量。例如:
WSAStartup(0x0202,&wsaData);
WSAStartup(MAKEWORD(2,2),&wsaData);
lpWSAData是一個指向WSADATA結構的指針。當該函數被調用時,返回關於Windows Sockets實現的詳細信息。
啓動函數WSAStartup():
終止:對於每一個WSAStartup函數的成功調用(即成功加載WinSock動態庫後),在最後都對應一個WSAC1eanLlp調用,以便釋放爲該應用程序分配的資源,終止對WinSock動態庫的使用。
WSAClean()函數。
9、編程.(客戶機與服務器)
答:/*----------------------------------------------------
* 程序: 服務器程序,TalkS_TCP.cpp
* 目的: 創建一個套接字,接收來自客戶的連接請求;
* 輸出來自客戶的信息;
* 通過鍵盤輸入信息,把信息發送給客戶。
*----------------------------------------------------
*/
#include <Winsock2.h> //管理WindowsSockets版本2函數的頭文件
#include <stdio.h> //提供輸入輸出函數
main() {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) { return; }
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return; }
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv; //定義一個地址結構體的變量
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
//htons把一個u_short類型從主機字節序轉換爲網絡字節順序
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5); //偵聽,一次可有5個在等待。
char sendBuf[100];
char recvBuf[100];
char temp[200];
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
int n;
SOCKET sockConn;
sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
while(1) { n=recv(sockConn,recvBuf,100,0);
if ( n>0 )
printf("%d chars from server: %s\n",n,recvBuf);
if('q'==recvBuf[0]) //對方想退出 {
send(sockSrv,"q",strlen("q")+1,0);
printf("chat end!\n");
break; }
printf("please input data:\n");
gets(sendBuf);//從標準輸入流中得到一行數據
send(sockConn,sendBuf,strlen(sendBuf)+1,0); //使用連接套接字,而不要監聽套接字;flags設置爲0即可}
closesocket(sockConn);
WSACleanup();//最後需要WSACleanUp()清除套接字。
}
客戶端程序代碼
/*----------------------------------------------------
* 程序: 客戶方程序,TalkC_TCP.cpp
* 目的: 創建一個套接字,通過網絡連接一個服務器
* 通過鍵盤輸入信息,把信息發送給服務器;
* 輸出來自服務器的信息。
*----------------------------------------------------
*/
#include <Winsock2.h>
#include <stdio.h>
main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err,n;
wVersionRequested = MAKEWORD( 1, 1);
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) { return; }
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return; }
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
if(connect(sockClient,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR))<0)
printf("Connect failed! \n"); //傳送數據所需要的變量定義
char sendBuf[100];
char recvBuf[100];
char temp[200];
int len=sizeof(SOCKADDR);
while(1) {
printf("please input data:\n");
gets(sendBuf);
send(sockClient,sendBuf,strlen(sendBuf)+1,0);
n=recv(sockClient,recvBuf,100,0);
if ( n>0 )
printf("%d chars from server: %s\n",n,recvBuf);
if ('q'==recvBuf[0])
{ send(sockClient,"q",strlen("q")+1,0);
printf("chat end!\n");
break; } sprintf(temp,"%s:%s",inet_ntoa(addrSrv.sin_addr),recvBuf);
printf("%s\n",temp); }
closesocket(sockClient);
WSACleanup();
}
10、MFC與套接功能有關的類(CAsyncSocket CSocket)
答:CAsyncSocket類;CScket類;
11、兩個類之間的區別聯繫?
答:CASyncSocket:異步方式。發送就返回結果無阻塞現象
CSocket:同步方式。只有發送完成後才返回結果有阻塞現象;
總的來說,CAsyncSocket是異步非阻塞類. CSocket是CAsyncSocket的派生類.是同步塞類.
12、兩個類基於流式套接字編程步驟?
答:CAyncSocket類:
服務器(server) 客戶機(client)
1、//構造一個套接字 //構造一個套接字
CAyncSocket sockSrvr; CAyncSocket sockClient;
2、//創建Socket句柄,綁定到 //創建Socket句柄,使用默認參數
指定的端口 sockClient.Create();
sockSrvr.Create(nPort);
3、//啓動監聽,時刻準備接受
連接請求
sockSrvr.Listen();
4、 //請求連接到服務器
sockClient.connet(strAddr.nport);
5、//構造一個新的空的套接字來接受連接
CAyncSocket sockRecv;
sockSrvr.Accept(sockRecv);
6、//接受數據 //發送數據
sockRecv.Receive(pBuf , nLen); sockClient.Send(pBuf , nLen));
7、//發送數據 //接收數據
sockRecv.Send(pBuf , nLen); sockClient.Receive(pBuf , nLen);
8、//關閉套接字對象 //關閉套接字對象
sockRecv.Close(); sockClient.Close();
CSocket類
1、 服務器端
(1)CSocket sockServ; // 創建空的服務器端監聽套接字對象。
(2)sockServ.Create( nPort ); // 用衆所周知的端口,創建監聽套接字對象的底層套接字句柄。
(3)sockServ.Listen(); // 啓動對於客戶端連接請求的監聽。
(4)CSocket sockRecv; // 創建空的服務器端連接套接字對象。
sockServ.Accept( sockRecv); // 接收客戶端的連接請求,並將其他的任務轉交給連接套接字對象。
(5)CSockFile* file ;
file = new CSockFile( &sockRecv); //創建文件對象並關聯到連接套接字對象。
6)CArchive* arIn, arOut;// 歸檔對象必須關聯到文件對象。
arIn = CArchive(&file, CArchive::load); //創建用於輸入的歸檔對象,
arOut = CArchive( &file, CArchive::store); // 創建用於輸出的歸檔對象。
(7)arIn >> dwValue; // 進行數據輸入。
adOut << dwValue; // 進行數據輸出。輸入或輸出可以反覆進行。
(8)sockRecv.Close();
sockServ.Close(); // 傳輸完畢,關閉套接字對象。
2.客戶端
(1)CSocket sockClient; // 創建空的客戶機端套接字對象。
(2)sockClient.Create( ); // 創建套接字對象的底層套接字。
(3)sockClient.Connect( strAddr, nPort ); // 請求連接到服務器。
(4)CSockFile* file ;
file = new CSockFile( &sockClent); //創建文件對象,並關聯到套接字對象。
(5)CArchive* arIn, arOut; // 歸檔對象必須關聯到文件對象。
arIn = CArchive(&file, CArchive::load); // 創建用於輸入的歸檔對象,
arOut = CArchive( &file, CArchive::store); // 創建用於輸出的歸檔對象。
(6)arIn >> dwValue; // 進行數據輸入。
adOut << dwValue; // 進行數據輸出。輸入或輸出可以反覆進行。
(7)sockClient.Close(); // 傳輸完畢,關閉套接字對象。
13、類能接受那些網絡事件?(6種)
答:FD_READ事件:通知有數據可讀。
FD_WRITE事件:通知可以寫數據。
FD_ACCEPT事件:通知監聽套接字有連接請求可以接受。
FD_CONNECT事件:通知請求連接的套接字,連接的要求已被處理。
FD_CLOSE事件:通知套接字已關閉。
FD_OOB事件:通知將有帶外數據到達。
13、什麼是WinInet,其作用?((編寫客戶機支持協議)
答:Windows Internet 擴展應用程序高級編程接口,是專爲開發具有Internet功能的客戶機應用程序而提供的。支持HTTP、FTP、Gopher協議;作用:藉助 WinInet 接口,可不必去了解 Winsock、TCP/IP 和特定 Internet 協議的細節就可以編寫出高水平的 Internet 客戶端程序。
14、MFC WinInet有哪些類?(5種)
答:會話類CInternetSession、連接類、網絡文件類、文件查詢類、異常類
15、FTP客戶機(利用WinInet 函數,編程步驟?)
答:(1).調用InternetAttemptConnection()函數測試主機與Internet的連接狀態
(2)調用InternetOpen()函數,創建HINTERNET會話根句柄
(3)調用InternetConnect()函數創建FTP連接句柄
(4)實現各種常見的FTP操作,依賴於FTP連接句柄,將它作爲函數的第一個參數
16、WinSocket I/O的兩種工作模式?什麼是阻塞,非阻塞.
答:阻塞模式、非阻塞模式;阻塞:稱同步模式,阻塞套接字的I/O操作工作情況比較確定,即調用、等待、返回。大部分情況下,I/O操作都能成功地完成,只是花費了等待的時間,容易編程;非阻塞模式:稱異步模式,使用非阻塞套接字,需要編寫更多的代碼,因爲必須恰當地把握調用I/O函數的時機,儘量減少無功而返的調用,還必須詳加分析每個Winsock調用中收到的錯誤,採取相應的對策,這種I/O操作的隨機性使得非阻塞套接字顯得難於操作。
17、阻塞解決方法,多線程機制,非阻塞解決方法?(五種套接字輸入模式)
答:阻塞的解決方法:多線程機制
非阻塞的解決方法:選擇(Select)、異步選擇(WSAAsyncSelect)、事件選擇(WSAEventSelect)、重疊I/O(Overlapped I/O)和完成端口(Completion Port)五種I/O模型
創建MFC下的工作線程步驟?
答:1.編輯實現控制函數
2.創建並啓動工作線程
18、Select模型?
答:select模型的操作步驟
使用 FD_ZERO宏初始化感興趣的每一個 fd_set集合。
使用 FD_SET宏將要檢查的套接字句柄添加到感興趣的每個 fd_set集合中,相當在指定的fd_set集合中,設置好要檢查的I/O活動。
調用 select函數,然後等待。select完成並返回後,會修改每個 fd_set結構,刪除那些不存在待決I/O操作的套接字句柄,在各個fd_set集合中返回符合條件的套接字。
根據select的返回值,使用 FD_ISSET宏,對每個fd_set集合進行檢查 ,判斷一個特定的套接字是否仍在集合中 ,便可判斷出哪些套接字存在着尚未完成(待決)的I/O操作。
知道了每個集合中“待決”的I/O操作之後,對相應的套接字的I/O進行處理 ,然後返回步驟1,繼續進行select處理。
SOCKET s; //定義一個套接字
fd_set fdread; //定義一個套接字集合變量
int ret; //返回值
//創建一個套接字,並接受連接
.......
// 管理該套接字上的輸入/輸出
while(TRUE)
{
FD_ZERO(&fdread); //調用select()之前要清除套接字集合
FD_SET(s, &fdread); //將套接字 s 添加到fdread集合中
//調用select()函數,並等待它的完成,
//這裏只是想檢查s是否有數據可讀
if ((ret = select(0, &fdread, NULL, NULL, NULL)) == SOCKET_ERROR)
{
…… //處理錯誤的代碼
}
//返回值大於零,說明有符合條件的套接字
//對於本例這個簡單的情況,select()的返回值應是1。
//如果程序處理更多的套接字,返回值可能大於1,
//應用程序應檢查特定的套接字是否在返回的集合中
if ( ret > 0)
{
if (FD_ISSET(s, &fdread))
{
…… // 對該套接字進行讀操作
}
}
}
19、HTTP會話週期?(4部分)
答:連接、請求、響應、斷開;
具體:
建立TCP/IP連接
Web客戶機向服務器發送HTTP請求
服務器向客戶機回送HTTP響應
斷開TCP/IP連接
20、CHtml View類 建一個web瀏覽器
21、STMP協議 POP3協議
答:簡單郵件傳送協議SMTP(Simple Mail Transfer Protocol),SMTP協議採用C/S模式,專用於電子郵件的發送,規定了發信人把郵件發送到收信人的電子郵箱的全過程中,SMTP客戶與SMTP服務器這兩個相互通信的進程之間應如何交換信息。
用來接收電子郵件的POP郵局協議最初是在1984年發表的RFC918中定義的,1985年的RFC937發表了它的第二個版本。隨着POP協議的廣泛使用,1988年的RFC1081又發表了它的第三版本,簡稱POP3
22、郵件格式(郵件頭 郵件體)
答:所有的信頭字段包括四部分,字段名(field name),緊跟冒號":" (colon),後跟字段體(field body),最後以回車換行符(CRLF)終止。即
信頭字段 = 字段名:字段體 <CRLF>
23、用WinSocket實現電子郵件中發送會話的步驟?
(1)啓動SMTP服務器,在指定的傳輸層端口監聽客戶端的連接請求,爲SMTP服務器保留的端口是25。
(2)客戶端設置Winsock連接的IP地址或域名,指定端口號,主動發出連接請求,連接到SMTP服務器。比如,網易的SMTP服務器的域名是smtp.163.com,監聽端口是25。
(3)服務器接收客戶端的連接請求,併發迴響應。客戶端應收到類似220 BigFox ESMTP service ready這樣的信息, 這就說明客戶端已經與服務器建立TCP/IP連接,成功地實現了第一步。
(4)客戶端和服務器分別向對方發送數據。
(5)客戶端或服務器分別讀取自己緩衝區中的數據。
(6)以上兩步是SMTP會話的主要部分,要按照SMTP協議的規定,按照一定順序,客戶向服務器發送命令,服務器向客戶發送應答,以上兩步要多次重複。
(7)會話完畢,關閉客戶端和服務器之間的連接。