第一篇:網(wǎng)絡(luò)編程實(shí)習(xí)報告
廣東應(yīng)屆生實(shí)習(xí)報告網(wǎng)在線編輯整理本文。
[實(shí)習(xí)目的]
通過理論聯(lián)系實(shí)際,鞏固所學(xué)的知識,提高處理實(shí)際問題的能力,并為自己能順利與社會環(huán)境接軌做準(zhǔn)備。[實(shí)習(xí)任務(wù)]Linux下網(wǎng)絡(luò)服務(wù)器開發(fā);本文總結(jié)了我對Linux下網(wǎng)絡(luò)服務(wù)器模型的認(rèn)識。[實(shí)習(xí)內(nèi)容]一.循環(huán)服務(wù)器1.循環(huán)服務(wù)器在同一個時刻只可以響應(yīng)一個客戶端的請求,對多個客戶程序的處理是采用循環(huán)的方式進(jìn)行;2.UDp循環(huán)服務(wù)器的實(shí)現(xiàn)非常簡單:UDp服務(wù)器每次從套接字上讀取一個客戶端的請求,處理,然后將結(jié)果返回給客戶機(jī);2.1.算法如下:socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}3.TCp循環(huán)服務(wù)器的實(shí)現(xiàn)也不難:TCp服務(wù)器接受一個客戶端的連接,然后處理,完成了這個客戶的所有請求后,斷開連接;3.1.算法如下:
socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
while(1)
{
read(...);
process(...);write(...);
}
close(...);
}3.2.TCp循環(huán)服務(wù)器一次只能處理一個客戶端的請求.只有在這個客戶的所有請求都滿足后,服務(wù)器才可以繼續(xù)后面的請求.這樣如果有一個客戶端占住服務(wù)器不放時,其它的客戶機(jī)都不能工作了.因此,TCp服務(wù)器一般很少用循環(huán)服務(wù)器模型的.二.并發(fā)服務(wù)器1.為了彌補(bǔ)循環(huán)TCp服務(wù)器的缺陷,人們又想出了并發(fā)服務(wù)器的模型。并發(fā)服務(wù)器的思想是每一個客戶機(jī)的請求并不由服務(wù)器直接處理,而是服務(wù)器創(chuàng)建一個子進(jìn)程來處理;2.使用并發(fā)服務(wù)器可以使服務(wù)器進(jìn)程在同一個時刻有多個子進(jìn)程和不同的客戶程序連接、通信;在客戶程序看來,服務(wù)器可以同時并發(fā)地處理多個客戶的請求;3.算法如下:socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
if(fork(..)==0)
{
close(...);while(1)
{
read(...);
廣東應(yīng)屆生實(shí)習(xí)報告網(wǎng)在線編輯整理本文。process(...);
write(...);
}
close(...);
exit(...);
}
close(...);
}4.TCp并發(fā)服務(wù)器可以解決TCp循環(huán)服務(wù)器客戶機(jī)獨(dú)占服務(wù)器的情況,改善了對客戶程序的響應(yīng)速度;不過也同時帶來了一個不小的問題:為了響應(yīng)客戶機(jī)的請求,服務(wù)器要創(chuàng)建子進(jìn)程來處理,而創(chuàng)建子進(jìn)程是一種非常消耗資源的操作,這明顯增加了系統(tǒng)調(diào)度的開銷;5.為了解決創(chuàng)建子進(jìn)程帶來的系統(tǒng)資源消耗,人們又想出了多路復(fù)用I/O模型.5.1.該模型一般用函數(shù)select和相關(guān)的四個宏定義:intselect(intfd,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout)
voidFD_SET(intfd,fd_set*fdset)
voidFD_CLR(intfd,fd_set*fdset)
voidFD_ZERO(fd_set*fdset)
intFD_ISSET(intfd,fd_set*fdset)5.2.一般的來說當(dāng)我們在向文件讀寫時,進(jìn)程有可能在讀寫時候阻塞,直到一定的條件滿足.比如我們從一個套接字讀數(shù)據(jù)時,可能緩沖區(qū)里面沒有數(shù)據(jù)可讀(通信的對方還沒有發(fā)送數(shù)據(jù)過來),這個時候我們的讀調(diào)用就會等待(阻塞)直到有數(shù)據(jù)可讀.如果我們不希望阻塞,我們的一個選擇是把socket設(shè)置為非阻塞模式來實(shí)現(xiàn);intsocketfd;socketfd=socket(AF_INET,SOCK_STREAM,0);fcntl(socketfd,F_SETFL,O_NONBLOCK);通過設(shè)置socket為非阻塞模式,可以實(shí)現(xiàn)“輪循”多個socket,當(dāng)企圖從一個沒有數(shù)據(jù)等待處理的非阻塞socket讀取數(shù)據(jù)時,函數(shù)立即返回,但是這種“輪循”會使CpU處于忙等待方式,降低了性能,select函數(shù)解決了這個問題;5.3.在我們調(diào)用select時進(jìn)程會一直阻塞直到以下的一種情況發(fā)生.1)有文件可以讀.2)有文件可以寫.3)超時所設(shè)置的時間到;5.4.算法如下:初始化(socket,bind,listen
while(1)
{設(shè)置監(jiān)聽讀寫文件描述符(FD_*);
調(diào)用select;
如果是傾聽套接字就緒,說明一個新的連接請求建立
建立連接(accept);
加入到監(jiān)聽文件描述符中去;
否則說明是一個已經(jīng)連接過的描述符
進(jìn)行操作(read或者write);}
多路復(fù)用I/O
廣東應(yīng)屆生實(shí)習(xí)報告網(wǎng)在線編輯整理本文。可以解決資源限制的問題.著模型實(shí)際上是將UDp循環(huán)模型用在了TCp上面.這也就帶來了一些問題.如由于服務(wù)器依次處理客戶的請求,所以可能會導(dǎo)致有的客戶會等待很久。三.I/O模型1.網(wǎng)絡(luò)服務(wù)器模型根據(jù)I/O模型的不同實(shí)現(xiàn)而來的;2.I/O模型分為同步I/O和異步I/O;同步I/O又包括阻塞I/O、非阻塞I/O、信號驅(qū)動I/O、多路復(fù)用I/O;可根據(jù)不同的要求利用不同的I/O模型實(shí)現(xiàn)不同是網(wǎng)絡(luò)服務(wù)器。[實(shí)習(xí)心得]通過近幾個月的實(shí)習(xí),基本上掌握了Linux下C語言網(wǎng)絡(luò)編程的一些算法和技巧,提高了自己的能力。專業(yè):計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)班級:03631學(xué)號:63103089姓名:呂亮亮——XX.05.23 
第二篇:網(wǎng)絡(luò)編程實(shí)習(xí)報告
[實(shí)習(xí)目的]
通過理論聯(lián)系實(shí)際,鞏固所學(xué)的知識,提高處理實(shí)際問題的能力,并為自己能順利與社會環(huán)境接軌做準(zhǔn)備。[實(shí)習(xí)任務(wù)]Linux下網(wǎng)絡(luò)服務(wù)器開發(fā)(基于C語言);本文總結(jié)了我對Linux下網(wǎng)絡(luò)服務(wù)器模型的認(rèn)識。[實(shí)習(xí)內(nèi)容]一.循環(huán)服務(wù)器1.循環(huán)服務(wù)器在同一個時刻只可以響應(yīng)一個客戶端的請求,對多個客戶程序的處理是采用循環(huán)的方式進(jìn)行; 2.UDp循環(huán)服務(wù)器的實(shí)現(xiàn)非常簡單:UDp服務(wù)器每次從套接字上讀取一個客戶端的請求,處理, 然后將結(jié)果返回給客戶機(jī);2.1.算法如下(UDp服務(wù)器): socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}3.TCp循環(huán)服務(wù)器的實(shí)現(xiàn)也不難:TCp服務(wù)器接受一個客戶端的連接,然后處理,完成了這個客戶的所有請求后,斷開連接;3.1.算法如下(TCp服務(wù)器):
socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
while(1)
{
read(...);
process(...);write(...);
}
close(...);
}3.2.TCp循環(huán)服務(wù)器一次只能處理一個客戶端的請求.只有在這個客戶的所有請求都滿足后, 服務(wù)器才可以繼續(xù)后面的請求.這樣如果有一個客戶端占住服務(wù)器不放時,其它的客戶機(jī)都不能工作了.因此,TCp服務(wù)器一般很少用循環(huán)服務(wù)器模型的.二.并發(fā)服務(wù)器1.為了彌補(bǔ)循環(huán)TCp服務(wù)器的缺陷,人們又想出了并發(fā)服務(wù)器的模型。并發(fā)服務(wù)器的思想是每一個客戶機(jī)的請求并不由服務(wù)器直接處理,而是服務(wù)器創(chuàng)建一個子進(jìn)程來處理;2.使用并發(fā)服務(wù)器可以使服務(wù)器進(jìn)程在同一個時刻有多個子進(jìn)程和不同的客戶程序連接、通信;在客戶程序看來,服務(wù)器可以同時并發(fā)地處理多個客戶的請求;3.算法如下(TCp服務(wù)器):socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
if(fork(..)==0)
{
close(...);while(1)
{
read(...);
process(...);
write(...);
}
close(...);
exit(...);
}
close(...);
}4.TCp并發(fā)服務(wù)器可以解決TCp循環(huán)服務(wù)器客戶機(jī)獨(dú)占服務(wù)器的情況,改善了對客戶程序的響應(yīng)速度;不過也同時帶來了一個不小的問題:為了響應(yīng)客戶機(jī)的請求,服務(wù)器要創(chuàng)建子進(jìn)程來處理,而創(chuàng)建子進(jìn)程是一種非常消耗資源的操作,這明顯增加了系統(tǒng)調(diào)度的開銷;5.為了解決創(chuàng)建子進(jìn)程帶來的系統(tǒng)資源消耗,人們又想出了多路復(fù)用I/O模型.5.1.該模型一般用函數(shù)select和相關(guān)的四個宏定義:intselect(intfd,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout)
voidFD_SET(intfd,fd_set*fdset)
voidFD_CLR(intfd,fd_set*fdset)
voidFD_ZERO(fd_set*fdset)
intFD_ISSET(intfd,fd_set*fdset)5.2.一般的來說當(dāng)我們在向文件讀寫時,進(jìn)程有可能在讀寫時候阻塞,直到一定的條件滿足.比如我們從一個套接字讀數(shù)據(jù)時,可能緩沖區(qū)里面沒有數(shù)據(jù)可讀(通信的對方還沒有發(fā)送數(shù)據(jù)過來),這個時候我們的讀調(diào)用就會等待(阻塞)直到有數(shù)據(jù)可讀.如果我們不希望阻塞,我們的一個選擇是把socket設(shè)置為非阻塞模式來實(shí)現(xiàn);int socketfd;socketfd=socket(AF_INET,SOCK_STREAM,0);fcntl(socketfd,F_SETFL,O_NONBLOCK);通過設(shè)置socket為非阻塞模式,可以實(shí)現(xiàn)“輪循”多個socket,當(dāng)企圖從一個沒有數(shù)據(jù)等待處理的非阻塞socket讀取數(shù)據(jù)時,函數(shù)立即返回,但是這種“輪循”會使CpU處于忙等待方式,降低了性能,select函數(shù)解決了這個問題;5.3.在我們調(diào)用select時進(jìn)程會一直阻塞直到以下的一種情況發(fā)生.1)有文件可以讀.2)有文件可以寫.3)超時所設(shè)置的時間到;5.4.算法如下(多路復(fù)用I/O模型):初始化(socket,bind,listen);
while(1)
{ 設(shè)置監(jiān)聽讀寫文件描述符(FD_*);
調(diào)用select;
如果是傾聽套接字就緒,說明一個新的連接請求建立
建立連接(accept);
加入到監(jiān)聽文件描述符中去;
否則說明是一個已經(jīng)連接過的描述符
進(jìn)行操作(read或者write);}
多路復(fù)用I/O可以解決資源限制的問題.著模型實(shí)際上是將UDp循環(huán)模型用在了TCp上面.這也就帶來了一些問題.如由于服務(wù)器依次處理客戶的請求,所以可能會導(dǎo)致有的客戶會等待很久。三.I/O模型1.網(wǎng)絡(luò)服務(wù)器模型根據(jù)I/O模型的不同實(shí)現(xiàn)而來的;2.I/O模型分為同步I/O和異步I/O;同步I/O又包括阻塞I/O、非阻塞I/O、信號驅(qū)動I/O、多路復(fù)用I/O;可根據(jù)不同的要求利用不同的I/O模型實(shí)現(xiàn)不同是網(wǎng)絡(luò)服務(wù)器。[實(shí)習(xí)心得] 通過近幾個月的實(shí)習(xí),基本上掌握了Linux下C語言網(wǎng)絡(luò)編程的一些算法和技巧,提高了自己的能力。專業(yè):計(jì)算機(jī)網(wǎng)絡(luò)技術(shù) 班級:03631 學(xué)號:63103089 姓名:呂亮亮——XX.05.23
第三篇:網(wǎng)絡(luò)編程實(shí)習(xí)作業(yè)
網(wǎng)絡(luò)編程實(shí)習(xí)作業(yè)
一. 實(shí)習(xí)內(nèi)容:
? 了解插口(socket)實(shí)現(xiàn)原理。
? 在某一種平臺(Linux,Unix系列或Windows系列)下進(jìn)行網(wǎng)絡(luò)客戶機(jī)-服務(wù)器編程。
二. 主要參考書目:
? W.Richard Stevens, “UNIX Network Programming Networking APIs: Scokets and XTI(Volume 1,Second Edition)”,清華大學(xué)出版社 Prentice-Hall International, Inc.或其中文版 “UNIX網(wǎng)絡(luò)編程(第1卷,第2版)” 經(jīng)典讀物,目前的最新版是第三版
? Douglas Comer,《用TCP/IP進(jìn)行網(wǎng)際互連 第3卷:客戶機(jī)-服務(wù)器編程和應(yīng)用(第2版)》 或其英文版 Internetworking With TCP/IP Vol III: Client-Server Programming And Application(Second Edition)以下簡稱《客戶機(jī)-服務(wù)器編程》
三. 實(shí)習(xí)題目:
1:編寫DAYTIME服務(wù)的UDP客戶機(jī)和服務(wù)器的實(shí)現(xiàn)。
基本要求:
當(dāng)服務(wù)器端收到客戶端的請求后,將當(dāng)前daytime返回給客戶端,客戶端收到該回應(yīng)后,將收到的daytime顯示到輸出中。
(其中在Linux或Unix環(huán)境中,當(dāng)前daytime的獲得參考函數(shù)time()和ctime())
2:熟悉Http協(xié)議的請求和響應(yīng)格式,編寫一個簡單的Http服務(wù)器。題目描述參考《自上而下計(jì)算機(jī)網(wǎng)絡(luò)》(第三版 作者James F.Kurose)第二章課后編程作業(yè)1。
基本要求:正確解析Http請求,實(shí)現(xiàn)簡單的GET請求回應(yīng)。模擬一個對象(如:文件index.html)的GET回應(yīng)(如:回應(yīng)一個字符串),對于其他的對象,則根據(jù)Http響應(yīng)格式回應(yīng)對象不存在信息。3 通過瀏覽器可檢測自己的程序。如:輸入,查看其響應(yīng)結(jié)果。對http請求的處理必須采用多進(jìn)程實(shí)現(xiàn),即主進(jìn)程負(fù)責(zé)等待請求連接,每當(dāng)收到一個請求后,產(chǎn)生一個子進(jìn)程對該請求做單獨(dú)處理,主進(jìn)程繼續(xù)等待新請求,子進(jìn)程在處理完其請求后結(jié)束自己。詳細(xì)要求參考課本要求。(多進(jìn)程編程參考函數(shù)fork())
要求:
源程序部分帶有必要的注釋,備有一份文檔說明各個程序中的思路和關(guān)鍵技術(shù)。注意,只能使用C語言編寫。可以是windows或者linux下可執(zhí)行,二種環(huán)境選擇一種即可。
評分標(biāo)準(zhǔn)
90% 以上 :在程序說明文檔中,可以體現(xiàn)出自己對本程序所用到的技術(shù)有較深刻的理解。
程序有較好的可讀性(關(guān)鍵部分的注釋比較詳細(xì))。
80% :符合要求,程序說明的比較詳細(xì),思路比較清楚。
70% :只有程序沒有說明文檔的,70%-60% :缺少說明文檔
60% 以下 :程序或說明文檔完全和別人的一樣(抄襲于被抄襲者一樣處理)。
注:作業(yè)包括程序部分(.c,.cpp,.h等源碼和.exe等可執(zhí)行文件,不要.obj 等其他文件)和程序說明文檔,文件大小最好不要超過1M。程序說明要體現(xiàn)出你所用到的關(guān)鍵技術(shù),要說清楚自己定義函數(shù)的功能及實(shí)現(xiàn),要有關(guān)鍵部分的流程圖。要按時交作業(yè),晚交的要相應(yīng)的扣分。請將程序打成一個包,包名統(tǒng)一采用“學(xué)號_姓名”形式,然后發(fā)到
network_tju@163.com
郵件的Title也是“學(xué)號_姓名”
請一定將學(xué)號放在前面
5截至日期:2009年4月20日
(注:1.以郵箱接收到的時間戳為準(zhǔn)。2.在提交作業(yè)時,請最好選擇發(fā)送并保存郵件,避免由于投遞失敗而導(dǎo)致作業(yè)無法按時完成。(就是避免死無對證)3.杜絕抄襲,請盡早開始著手這項(xiàng)作業(yè))
第四篇:《網(wǎng)絡(luò)編程課程設(shè)計(jì)》實(shí)習(xí)總結(jié)
河北科技師范學(xué)院歐美學(xué)院
實(shí)習(xí)類型教學(xué)實(shí)習(xí)實(shí)習(xí)單位河北科技師范學(xué)院歐美學(xué)院實(shí)習(xí)起止時間年月 年日 指導(dǎo)教師劉正林所在院(系)信息技術(shù)系專業(yè)班級網(wǎng)專1101學(xué)生姓名崔珺珺學(xué)號
一、實(shí)習(xí)的基本概況
(一)理論指導(dǎo)
根據(jù)實(shí)訓(xùn)內(nèi)容自行確定
(二)項(xiàng)目情況
項(xiàng)目名稱:企業(yè)門戶網(wǎng)站
開發(fā)環(huán)境:Windows XP
項(xiàng)目分工情況:
我的任務(wù):制作企業(yè)門戶網(wǎng)站框架
二、實(shí)習(xí)過程或步驟
新建一個記事本文件,開始填寫代碼,我所做的是一家廣告公司的主頁面,所以題目的代碼是這么寫的:
這樣,超鏈接的字體是黑色的,但鼠標(biāo)指向它以后就是紅色的。
從互聯(lián)網(wǎng)下載一張名為1后綴為JPG的圖片,“XX廣告,行業(yè)的領(lǐng)頭者”下一步編寫代碼,并且將該1.JPG放入主頁所在的文件夾,代碼部分如下:

對網(wǎng)頁上半部分的框架表格進(jìn)行處理,的對字體、字號進(jìn)行設(shè)置,代碼如下:
了解了一些代碼的含義,比如
為了使網(wǎng)頁有簡單的交互性在主頁上設(shè)置了一個登錄界面和按鈕,代碼如下
我連接了一個新建名為1.HTML的網(wǎng)頁,主要是自己弄不太懂有關(guān)數(shù)據(jù)庫的知識,所以只能簡單的編寫,這樣不論在用戶名、密碼輸入什么,都能跳入第二個頁面。
進(jìn)行了左側(cè)表格框架的設(shè)計(jì)編寫,代碼如下:
服務(wù)導(dǎo)航
三、實(shí)習(xí)感受
(一)成績與收獲
通過這次網(wǎng)頁制作實(shí)習(xí)課程,我更加深入的了解了各種代碼語言的作用,從互聯(lián)網(wǎng)上學(xué)習(xí)了更多的知識。學(xué)習(xí)制作網(wǎng)頁,必須先從學(xué)習(xí)HTML語言做起,弄清楚各種語言在制作網(wǎng)頁中的重要作用,通過這次綜合性實(shí)驗(yàn),我已經(jīng)可以靈活運(yùn)用所學(xué)知識和技巧制作簡單的網(wǎng)頁。實(shí)驗(yàn)過程中,我盡量充分運(yùn)用老師教過的知識,對所學(xué)知識有一定的鞏固作用,為了做出更好的效果我也翻閱參考了其他的資料,學(xué)習(xí)到了更多網(wǎng)頁處理的技巧,制作網(wǎng)頁過程中我遇到了不少的問題,通過詢問同學(xué)和查找資料都獲得了 解決的辦法,這次實(shí)踐對我而言是一個不小的提升,在實(shí)踐過程中學(xué)習(xí)鞏固對知識能有更深的記憶。網(wǎng)頁制作是一門很實(shí)用的學(xué)科,值得我們以后更深入的去學(xué)習(xí)?,F(xiàn)在我掌握的制作知識還是太少,需要以后多與老師、同學(xué)們交流,自己在網(wǎng)絡(luò)上也需要更加深入的挖掘有關(guān)知識。
(二)問題與不足
對一些代碼的作用不了解,亂加運(yùn)用導(dǎo)致頁面混亂,而且缺少獨(dú)自處理錯誤與難題的能力,對于有些知識僅是一看就過,其實(shí)自己根本沒有掌握,而且掌握了的也是一知半解,沒有將知識加以用工,總是想做些什么但是真到了做的時候不會,還得去翻書。
第五篇:網(wǎng)絡(luò)編程實(shí)驗(yàn)報告
實(shí)驗(yàn)一 TCP Socket API程序設(shè)計(jì)
一、預(yù)備知識
1.網(wǎng)絡(luò)編程基本概念
網(wǎng)絡(luò)上的計(jì)算機(jī)間的通訊,實(shí)質(zhì)上是網(wǎng)絡(luò)中不同主機(jī)上的程序之間的通訊。在互聯(lián)網(wǎng)中使用IP地址來標(biāo)識不同的主機(jī),在網(wǎng)絡(luò)協(xié)議中使用端口號來標(biāo)識主機(jī)上不同進(jìn)程,即使用(IP地址,端口號)二元組。
套接字(Socket)用于描述IP地址和端口,是一個通信鏈的句柄,通信時一個網(wǎng)絡(luò)程序?qū)⒁獋鬏數(shù)囊欢涡畔懭胨谥鳈C(jī)的Socket中,該Socket通過與網(wǎng)絡(luò)接口卡相連的傳輸介質(zhì)將這段信息發(fā)送到另一臺主機(jī)的Socket中,以供其他程序使用。
圖1-1 TCP通信流程 2.TCP通信流程
TCP程序是面向連接的,程序運(yùn)行后,服務(wù)器一直處于監(jiān)聽狀態(tài),客戶端與服務(wù)器通信之前必須首先發(fā)起連接請求,由服務(wù)器接收請求并在雙方之間建立連接后才可以互相通信。
二、實(shí)驗(yàn)?zāi)康?/p>
1.了解Winsock API編程原理; 2.掌握TCP Socket程序的編寫; 3.了解C/S模式的特點(diǎn); 4.學(xué)會解決實(shí)驗(yàn)中遇到的問題。
三、實(shí)驗(yàn)任務(wù)
使用Winsock API相關(guān)類實(shí)現(xiàn)TCP Socket通信程序,并能成功運(yùn)行。
四、實(shí)驗(yàn)環(huán)境及工具
1.Windows2000/XP/7 2.Visual C++開發(fā)平臺 3.Visual Studio2010
五、實(shí)驗(yàn)內(nèi)容和步驟
參照《Visual C++網(wǎng)絡(luò)編程教程》書中81頁,TCP Socket API程序設(shè)計(jì)。連接:
void CChatClientDlg::OnConnect(){
WSADATA wsd;
//WSADATA結(jié)構(gòu)
WSAStartup(MAKEWORD(2,2),&wsd);
//加載協(xié)議,使用Winsock 2.2版
m_client = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建流式套接字
//服務(wù)器地址
sockaddr_in serveraddr;
UpdateData();
if(ServerIP.IsBlank())
{
AfxMessageBox(“請指定服務(wù)器IP!”);
return;
}
if(sPort.IsEmpty())
{
AfxMessageBox(“請指定端口!”);
return;
}
//獲取服務(wù)器進(jìn)程的IP和端口
BYTE nFild[4];
CString sIP;
ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]);
sIP.Format(“%d.%d.%d.%d”,nFild[0],nFild[1],nFild[2],nFild[3]);
//設(shè)置服務(wù)器地址結(jié)構(gòu)的內(nèi)容
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.S_un.S_addr = inet_addr(sIP);
serveraddr.sin_port = htons(atoi(sPort));
//發(fā)起連接須指明要訪問的服務(wù)器進(jìn)程地址,這個地址存儲在serveraddr中
if(connect(m_client,(sockaddr*)&serveraddr,sizeof(serveraddr))!= 0)
{
MessageBox(“連接失敗”);
return;
}
else
{
m_ListWords.AddString(“連接服務(wù)器成功!”);
m_ListWords.SetTopIndex(m_ListWords.GetCount()1);
ServerIP.EnableWindow();
ServerPort.EnableWindow();
m_ButtonConnect.EnableWindow();
m_ButtonDisconnect.EnableWindow(false);
m_EditWords.EnableWindow(false);
m_ButtonSend.EnableWindow(false);
m_ButtonExit.EnableWindow();}
“發(fā)送”按鈕事件過程代碼如下:
void CChatClientDlg::OnSend(){
//向服務(wù)器發(fā)送信息
UpdateData();
if(m_sWords.IsEmpty())
{
AfxMessageBox(“發(fā)送的消息不能為空!”);
return;
}
//開始發(fā)送數(shù)據(jù)
int i = send(m_client,m_sWords.GetBuffer(0),m_sWords.GetLength(),0);
m_ListWords.AddString(“發(fā)送:” + m_sWords);
m_ListWords.SetTopIndex(m_ListWords.GetCount()1);
closesocket(m_client);
ServerIP.EnableWindow();
ServerPort.EnableWindow();
m_ButtonConnect.EnableWindow();
m_ButtonDisconnect.EnableWindow(false);
m_EditWords.EnableWindow(false);
m_ButtonSend.EnableWindow(false);
m_ButtonExit.EnableWindow();} “清空”按鈕的事件過程: m_ListWords.ResetContent();“關(guān)于”按鈕的事件過程: CAboutDlg dlgAbout;dlgAbout.DoModal();
服務(wù)器端: 開始監(jiān)聽代碼:
void CChatServerDlg::OnListen(){
WSADATA wsd;
//WSADATA結(jié)構(gòu)
WSAStartup(MAKEWORD(2,2),&wsd);
//加載協(xié)議棧,使用Winsock 2.2版
m_server = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建流式套接字
//將網(wǎng)絡(luò)中的事件關(guān)聯(lián)到窗口的消息函數(shù)中,定義消息號為20000,偵測客戶端的連接請求
WSAAsyncSelect(m_server,m_hWnd,20000,FD_ACCEPT);
m_client = 0;
BYTE nFild[4];
CString sIP;
UpdateData();
if(ServerIP.IsBlank())
{
AfxMessageBox(“請?jiān)O(shè)置IP地址!”);
return;
}
if(sPort.IsEmpty())
{
AfxMessageBox(“請?jiān)O(shè)置監(jiān)聽端口!”);
return;
}
ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]);
sIP.Format(“%d.%d.%d.%d”,nFild[0],nFild[1],nFild[2],nFild[3]);
//服務(wù)器地址
sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.S_un.S_addr = inet_addr(sIP);
serveraddr.sin_port = htons(atoi(sPort));
//綁定地址
if(bind(m_server,(sockaddr*)&serveraddr,sizeof(serveraddr)))
{
MessageBox(“綁定地址失敗.”);
return;
}
//監(jiān)聽開始,服務(wù)器等待連接請求的到來
listen(m_server,5);
m_ListWords.AddString(“監(jiān)聽開始:”);
m_ListWords.AddString(“地址” + sIP + “ 端口” + sPort);
m_ListWords.AddString(“等待客戶端連接??”);
//界面完善
m_ListWords.SetTopIndex(m_ListWords.GetCount()-1);
ServerIP.EnableWindow(false);
ServerPort.EnableWindow(false);
m_ButtonListen.EnableWindow(false);
m_ButtonStopListen.EnableWindow();
m_ButtonClear.EnableWindow();
m_ButtonExit.EnableWindow(false);} “停止監(jiān)聽”按鈕事件過程代碼如下: void CChatServerDlg::OnStopListen(){
//停止監(jiān)聽
closesocket(m_server);
m_ListWords.AddString(“停止監(jiān)聽”);
m_ListWords.SetTopIndex(m_ListWords.GetCount()1);} “斷開”按鈕事件過程代碼如下: void CChatServerDlg::OnDisconnect(){
closesocket(m_client);
m_ListWords.AddString(“與客戶端斷開”);
m_ListWords.SetTopIndex(m_ListWords.GetCount()1);
//界面完善
m_ButtonDisconnect.EnableWindow();
m_EditWords.EnableWindow();
m_ButtonSend.EnableWindow();} ReceiveData()函數(shù)代碼如下:
void CChatServerDlg::ReceiveData(){
//接收客戶端的數(shù)據(jù)
char buffer[1024];
int num = recv(m_client,buffer,1024,0);
buffer[num] = 0;
CString sTemp;
sTemp.Format(“收到:%s”,buffer);
m_ListWords.AddString(sTemp);//顯示信息
m_ListWords.SetTopIndex(m_ListWords.GetCount()1);
closesocket(m_client);//關(guān)閉與客戶端通信的Socket
WSAAsyncSelect(m_server,m_hWnd,20000,FD_ACCEPT);//準(zhǔn)備接收新的客戶端連接
//界面完善
m_ButtonDisconnect.EnableWindow(false);
m_EditWords.EnableWindow(false);
m_ButtonSend.EnableWindow(false);} 服務(wù)器的初始化代碼如下: //界面初始化
m_ButtonStopListen.EnableWindow(false);m_ButtonDisconnect.EnableWindow(false);m_ButtonClear.EnableWindow(false);m_EditWords.EnableWindow(false);m_ButtonSend.EnableWindow(false);
運(yùn)行結(jié)果:
六、思考題
1.用Winsock API編程時,主要進(jìn)行哪些通行的操作步驟? 2.闡述C/S模式的通信過程。答:
1.通行的操作
1.Winsock的打開(WSAStartup())。2.建立套接字(socket()或WSASocket())。3.地址綁定(bind())。
4.服務(wù)器監(jiān)聽連接(listen())。
5.客戶端提出連接申請(connect()或WSAConnect())。6.服務(wù)器接收客戶端的連接請求(accept()或WSAAccept())。7.數(shù)據(jù)的發(fā)送(send()或WSASend(),sendto()或WSASendTo())。8.數(shù)據(jù)的接收(recv()或WSARecv(),recvfrom()或WSARecvfrom())。9.關(guān)閉套接字(closesocket())。10.關(guān)閉Winsock(WSACleanup())。
2通信過程