版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
哈爾濱理工大學(xué)課程設(shè)計(jì)題目:共享參數(shù)的多線程編程(網(wǎng)絡(luò)安全課程設(shè)計(jì))院、系:計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院網(wǎng)絡(luò)工程系班級(jí):學(xué)號(hào):姓名:同組成員:指導(dǎo)教師:成績(jī):2014年06月27日一系統(tǒng)設(shè)計(jì)的目標(biāo)了解并掌握C/S模式下TCP的連接以及并發(fā)服務(wù)器的實(shí)現(xiàn)。了解并掌握多線程在實(shí)現(xiàn)共享參數(shù)方面的方法。3,掌握共享參數(shù)多線程編程。二系統(tǒng)原理實(shí)驗(yàn)環(huán)境:Ubuntu12.04系統(tǒng),GCC編譯器1),建立套接字并在某一約定端口上等待接收客戶請(qǐng)求;2),當(dāng)接收到來(lái)自客戶端的服務(wù)請(qǐng)求后:建立一新線程來(lái)處理,同時(shí)主線程繼續(xù)等待其他客戶連接。當(dāng)新線程處理完成后,關(guān)閉新線程與客戶的通信鏈路并終止新線程。.關(guān)閉服務(wù)器。圖2-1工作過(guò)程三系統(tǒng)功能分析.C/S結(jié)構(gòu)介紹C/S結(jié)構(gòu),即大家熟知的客戶機(jī)和服務(wù)器結(jié)構(gòu)。它是軟件系統(tǒng)體系結(jié)構(gòu),通過(guò)它可以充分利用兩端硬件環(huán)境的優(yōu)勢(shì),將任務(wù)合理分配到Client端和Server端來(lái)實(shí)現(xiàn),降低了系統(tǒng)的通訊開(kāi)銷。(Client/Server或客戶/服務(wù)器模式):Client和Server常常分別處在相距很遠(yuǎn)的兩臺(tái)計(jì)算機(jī)上,Client程序的任務(wù)是將用戶的要求提交給Server程序,再將Server程序返回的結(jié)果以特定的形式顯示給用戶;Server程序的任務(wù)是接收客戶程序提出的服務(wù)請(qǐng)求,進(jìn)行相應(yīng)的處理,再將結(jié)果返回給客戶程序。C/S模式下TCP方式服務(wù)器程序流程(多進(jìn)程):程序初始化填寫本機(jī)地址信息綁定并監(jiān)聽(tīng)一個(gè)固定的端口收到Client的連接后建立一個(gè)socket連接產(chǎn)生一個(gè)新的線程與Client進(jìn)行通信和信息處理子通信結(jié)束后中斷與Client的連接客戶端程序流程:程序初始化填寫服務(wù)器地址信息連接服務(wù)器與服務(wù)器通信和信息處理通信結(jié)束后斷開(kāi)連接.套接字技術(shù)所謂socket通常也稱作"套接字”,應(yīng)用程序通常通過(guò)"套接字”向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。以J2SDK-1.3為例,Socket和ServerSocket類庫(kù)位于包中。ServerSocket用于服務(wù)器端,Socket是建立網(wǎng)絡(luò)連接時(shí)使用的。在連接成功時(shí),應(yīng)用程序兩端都會(huì)產(chǎn)生一個(gè)Socket實(shí)例,操作這個(gè)實(shí)例,完成所需的會(huì)話。對(duì)于一個(gè)網(wǎng)絡(luò)連接來(lái)說(shuō),套接字是平等的,并沒(méi)有差別,不因?yàn)樵诜?wù)器端或在客戶端而產(chǎn)生不同級(jí)別。不管是Socket還是ServerSocket它們的工作都是通過(guò)Socketlmpl類及其子類完成的。.多線程并發(fā)服務(wù)器的實(shí)現(xiàn)線程,有時(shí)被稱為輕量級(jí)進(jìn)程(LightweightProcess,LWP),是程序執(zhí)行流的最小單元。一個(gè)標(biāo)準(zhǔn)的線程由線程ID,當(dāng)前指令指針(PC),寄存器集合和堆棧組成。另外,線程是進(jìn)程中的一個(gè)實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位,線程自己不擁有系統(tǒng)資源,只擁有一點(diǎn)兒在運(yùn)行中必不可少的資源,但它可與同屬一個(gè)進(jìn)程的其它線程共享進(jìn)程所擁有的全部資源。在一個(gè)進(jìn)程中的多個(gè)線程之間,可以并發(fā)執(zhí)行,甚至允許在一個(gè)進(jìn)程中所有線程都能并發(fā)執(zhí)行;同樣,不同進(jìn)程中的線程也能并發(fā)執(zhí)行,充分利用和發(fā)揮了處理機(jī)與外圍設(shè)備并行工作的能力?;诙嗑€程的Linux系統(tǒng)下并發(fā)服務(wù)器能夠同時(shí)并有效地運(yùn)行多個(gè)任務(wù)。采用這種并發(fā)系統(tǒng)結(jié)構(gòu),既增加了服務(wù)器程序的功能,又提高了其性能。只有一個(gè)處理器時(shí),多個(gè)線程不能真正地并行執(zhí)行。然而,經(jīng)過(guò)固定的時(shí)間間隔或當(dāng)一個(gè)線程處于等待狀態(tài)時(shí),就可從一個(gè)線程切換到另一線程,實(shí)現(xiàn)多個(gè)線程重疊執(zhí)行。在有多個(gè)CPU的計(jì)算機(jī)上,如果底層系統(tǒng)支持,則多個(gè)線程可真正地被并行執(zhí)行服務(wù)的并行性潛力得以開(kāi)發(fā)。四系統(tǒng)實(shí)現(xiàn)下面我們通過(guò)一個(gè)具體的實(shí)例來(lái)說(shuō)明多線程并發(fā)服務(wù)器的具體實(shí)現(xiàn):服務(wù)器端:循環(huán)等候客戶連接請(qǐng)求一旦有客戶連接請(qǐng)求開(kāi)啟一個(gè)子線程接受并處理客戶請(qǐng)求連接成功后向客戶發(fā)送歡迎信息,接著接受來(lái)自客戶的信息,然后將客戶信息反轉(zhuǎn)后再返回給客戶端主線程繼續(xù)等待其他客戶請(qǐng)求服務(wù)器具有同時(shí)處理多個(gè)用戶的能力;客戶端:首先與服務(wù)器建立連接,接著接收用戶輸入的客戶名字,將名字發(fā)給服務(wù)器;然后向服務(wù)器發(fā)送數(shù)據(jù),進(jìn)行交互,接受服務(wù)器的反饋信息并顯示之后繼續(xù)等待用戶輸入直至用戶輸入ctrl+c結(jié)束通信客戶端接到輸入ctrl+c后客戶端關(guān)閉連接并退出。實(shí)驗(yàn)截圖客戶端在命令行中應(yīng)輸入欲連接服務(wù)器的地址或域名,如圖所示。覆knight?knight-Aspire-47501~kntght@knight-Aspire-4750*/client127-0,0*1ServerMessage:Welcometomyserver*Inputyourrbane:cltent991Inputyournessage(nax:I960)圖4-1客戶端請(qǐng)求連接
用戶給出客戶端名稱,服務(wù)器端顯示,如圖所示,服務(wù)器端通過(guò)用戶名來(lái)顯示信息的來(lái)源,并對(duì)信息進(jìn)行處理返回客戶端,客戶端在屏幕輸出,如圖?0@knight?knight-Aspire-475D:~gcc:致命錯(cuò)誤:編譯中斷。沒(méi)有輸入文件-oclientclienttic127.0,0.1knight@knight-Aspire-4759:./client127.0,0.1Binderror*:Connectionrefusedknight@knight-Aspire-4759:gcc-oserverserver^cgcc:錯(cuò)誤:server.c::沒(méi)有那個(gè)文件或目錄gcc:致命錯(cuò)誤:沒(méi)有輸入文件編譯中斷。-Lpthread-Lpthreadknight@knight-Aspire-4759:*/serverbash:./server:沒(méi)有那個(gè)文件或目錄knight@knight-Aspire-4759:gcc-oserverserver^cgcc:錯(cuò)誤:server.c::-Lpthread-Lpthreadknight@knight-Aspire-4759:gcc-oserverserver^cknight@knight-Aspire-4759:*/serverYougetaconnectfrom127*0*0.1ClientnameisclientOOl.messagerwoshiknlghtmessage:nihaomfe"
message:ntrensht
message:nizhidaoRecetvefromclient(client?01)Yougetamessagerwoshiknlghtmessage:nihaomfe"
message:ntrensht
message:nizhidaoRecetvefromclient(client?02)Recetvefromclient(client?01)Recetvefromclient(client?02)圖4-2.服務(wù)器顯示客戶端,服務(wù)器接受數(shù)據(jù)并處理?00knight@knight-Aspire-4750:~kntght@knight-Asptre-4750:gcc-oeLtentclientkntghtgiknight-Asptre-47501~5*/clientUsager./client<IPaddress>kntghtgiknight-Aspire-47501~5*/client127.9.@*1ServerMessage:Welcometoryserver*Inputyourname:cttentQOlInputyournessage(naxr1000):woshtkntghtTheconvinceofyourmessageithgtnkthsowInputyournessage(naxrlOOO):ntrenshtTheconvinceofyourmessage:thsnertnsowInputyournessage(naxr1060)圖4-3圖4-3客戶1發(fā)送數(shù)據(jù)并得到回顯?◎薊knight@knight-Aspire-475D:~knight?knight-A5pi「日-4750*/client127.0.@*LServerMessage:Wetcometomyserver*Inputyourname:cttent902Inputyournessage(naxr1000):nthaomaTheconvinceofyourmessage:amoahinInputyournessage(naxr1000):ntzhtdaoTheconvinceofyourmessage:oadihztnInputyournessage(naxr1060)圖4-4圖4-4.客戶2發(fā)送信息給服務(wù)器,并接受服務(wù)器處理后的數(shù)據(jù),在屏幕輸出?魯國(guó)knighc@knight-Aspire-475D:~kntght@knight-Aspire-4759:gcc-oclientclientkntght@knight-Aspire-47591./clientUsager./client<IPaddress>kntght|gknight-Aspire-47591~5*/client127*0.0.1ServerMessage:Welcometonyserver*Inputyourname:cttentQOlInputyournessage(naxr1000):woshiknightTheconvinceofyourmessageithginkthsowInputyournessage(naxr1000):ntrenshtTheconvinceofyourmessage:thsnertnsowInputyournessage(naxr1000):ACkntght|gknight-Aspire-47501圖4-5.客戶端可通過(guò)輸入ctrl+c來(lái)釋放連接,服務(wù)器端給予應(yīng)答及釋放連接,并再次在屏幕顯示客戶端數(shù)據(jù).建立套接字并在某一約定端口上等待接收客戶請(qǐng)求;1使用socket。創(chuàng)建套接字2將創(chuàng)建的套接字綁定在指定的地址結(jié)構(gòu)。3Listen()函數(shù)設(shè)置套接字為監(jiān)聽(tīng)模式,使服務(wù)器進(jìn)入被動(dòng)打開(kāi)狀態(tài),等待客戶請(qǐng)求.當(dāng)接收到來(lái)自客戶端的服務(wù)請(qǐng)求后:建立一新線程來(lái)處理,同時(shí)主線程繼續(xù)等待其他客戶連接。當(dāng)新線程處理完成后,關(guān)閉新線程與客戶的通信鏈路并終止新線程。1服務(wù)器主線程接受客戶請(qǐng)求,建立連接并fork新的線程,調(diào)用savedata()線程安全函數(shù),調(diào)用create_once()函數(shù)產(chǎn)生TSD關(guān)鍵字,再與該客戶通信。主線程繼續(xù)接受下一個(gè)客戶請(qǐng)求。2接受客戶發(fā)來(lái)的數(shù)據(jù)按先后順序存在數(shù)據(jù)緩沖區(qū)。.關(guān)閉服務(wù)器。以上過(guò)程如圖4-6主繚呈工作線程主繚呈工作線程圖4-6附錄:源程序代碼:〃所需頭文件#include<pthread.h>#include<unistd.h>#include<stdio.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<netdb.h>#include<string.h>#include<stdlib.h>#definePORT1234#defineBACKLOG2#defineMAXCHARSIZE1000voidpro_client(intconnectfd,structsockaddr_inclient);void*exec_thread(void*arg);voidsave_data(char*recvbuf,intlen,char*cli_data);structARG{intconnfd;structsockaddr_inclient;};structARG*arg;intmain(void){intlistenfd,connectfd;structsockaddr_inserver,client;intsin_size;intopt=SO_REUSEADDR;pthread_ttid;sin_size=sizeof(structsockaddr_in);if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("Createsocketfailed.");exit(-1);}setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));bzero(&server,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr.s_addr=htonl(INADDR_ANY);if(bind(listenfd,(structsockaddr*)&server,sizeof(structsockaddr))==-1){perror("Binderror.");exit(-1);}if(listen(listenfd,BACKLOG)==-1){perror("Listenerror.");exit(-1);}while⑴{if((connectfd=accept(listenfd,(structsockaddr*)&client,&sin_size))==-1){perror("Accepterror.");exit(-1);}arg=(structARG*)malloc(sizeof(structARG));arg->connfd=connectfd;memcpy((void*)&arg->client,&client,sizeof(client));if(pthread_create(&tid,NULL,start_routine,(void*)arg)){perror("Pthread_createerror.\n");exit(-1);}}close(listenfd);}//TSD關(guān)鍵字變量keystaticpthread_key_tkey;〃變量once并賦值staticpthread_once_tonce=PTHREAD_ONCE_INIT;//ST_DATA結(jié)構(gòu),用于存儲(chǔ)TSDstructDATA_THR{intindex;};〃析構(gòu)函數(shù)key_destro(),在線程退出時(shí)該析構(gòu)函數(shù)將被調(diào)用,,以釋放為TSD分配的空間staticvoidkey_destroy(void*buf){free(buf);}〃定義函數(shù),以產(chǎn)生TSD關(guān)鍵字staticvoidbuffer_key_alloc(){pthread_key_create(&key,key_destroy);}〃定義函數(shù)save_data()voidsave_data(char*recvbuf,intlen,char*cli_data){structDATA_THR*data;pthread_once(&once,buffer_key_alloc);if((data=(structDATA_THR*)pthread_getspecific(key))==NULL){data=(structDATA_THR*)calloc(1,sizeof(structDATA_THR));pthread_setspecific(key,data);data->index=0;}inti;for(i=0;i<len;i++)cli_data[data->index++]=recvbuf[i];cli_data[data->index]='\0';//■■■■■■voidpro_client(intconnectfd,structsockaddr_inclient){charrecvbuf[MAXCHARSIZE];charsendbuf[MAXCHARSIZE];charclient_name[MAXCHARSIZE];charclient_data[5000];intrecvlen,i;printf("Yougetaconnectfrom%s\n",inet_ntoa(client.sin_addr));send(connectfd,"Welcometomyserver.\n",22,0);recvlen=recv(connectfd,client_name,MAXCHARSIZE,0);if(recvlen==0){close(connectfd);printf("Clientdisconnected.\n");return;elseif(recvlen<0){close(connectfd);printf("Connectbroked.\n");return;}client_name[recvlen]='\0';printf("Clientnameis%s.\n",client_name);bzero(recvbuf,1000);while(recvlen=recv(connectfd,recvbuf,MAXCHARSIZE,0)){save_data(recvbuf,recvlen,client_data);recvbuf[recvlen]='\0';printf("Receivefromclient(%s)message:%s\n",client_name,recvbuf);for(i=0;i<recvlen;i++)sendbuf[i]=recvbuf[recvlen-i-1];send(connectfd,sendbuf,strlen(sendbuf),0);bzero(recvbuf,1000);printf("Client:%sdisconnected.User'sdata:%s\n",client_name,client_data);close(connectfd);〃實(shí)現(xiàn)線程的執(zhí)行函數(shù)void*exec_thread(void*arg){structARG*info;info=(structARG*)arg;pro_client(info->connfd,info->client);free(arg);pthread_exit(NULL);}客戶端程序:#include<unistd.h>#include<sys/socket.h>#include<netinet/in.h>#include<netdb.h>#include<string.h>#include<stdlib.h>#include<stdio.h>#definePORT1234#defineMAXDATASIZE1000;intmain(intargc,char*argv[])intfd,numbytes;charbuf[1000];structhostent*he;structsockaddr_inserver;inti=1;if(argc!=2){printf("Usage:%s<IPaddress〉\n",argv[0]);exit(-1);}〃獲得服務(wù)器的地址信息if((he=gethostbyname(argv[1]))==NULL)perror("gethostbynameerror.");exit(-1);}if((fd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("Createsocketfailed.");exit⑴;}bzero(&server,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr=*((structin_addr*)he->h_addr);if(connect(fd,(structsockaddr*)&server,sizeof(structsockaddr))==-1){perror("Binderror.");exit⑴;}if((numbytes=recv(fd,buf,1000,0))==-1){perror("recverror.");exit⑴;}buf[numbytes]='\0';printf("ServerMessage:%s\n",buf);printf("Inputyourname:");scanf("%s",buf);if((numbytes=send(fd,buf,strlen(buf),0))==-1){perror("Senderror.");exit⑴;}bzero(buf,1000);while(i){printf("Inputyourmessage(max:1000):");scanf("%s",buf);if(strlen(buf)<1)i=0;if((numbytes=send(fd,buf,strlen(buf),0))==-1){perror("Senderror.");exit⑴;}bzero(buf,1000);if((n
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年股權(quán)激勵(lì)合同:股權(quán)獎(jiǎng)勵(lì)與業(yè)績(jī)掛鉤條款3篇
- 2025年度濾袋材料費(fèi)用合同采購(gòu)與項(xiàng)目進(jìn)度管理合同3篇
- 2025年度網(wǎng)絡(luò)安全防護(hù)設(shè)備采購(gòu)合同范本與安全等級(jí)保護(hù)2篇
- 學(xué)生校園欺凌情況調(diào)查問(wèn)卷
- 敢于擔(dān)當(dāng)善于化解難題體會(huì)
- 護(hù)理人力資源管理1
- 黨史知識(shí)競(jìng)賽題庫(kù)及答案-一起學(xué)習(xí)黨史吧
- 八一南昌起義的意義是什么
- 2024版地方特色農(nóng)產(chǎn)品購(gòu)銷合作合同版
- 2024集體土地租賃協(xié)議書(shū)
- 最新VTE指南解讀(靜脈血栓栓塞癥的臨床護(hù)理指南解讀)
- 生產(chǎn)計(jì)劃控制程序文件
- 山東省濟(jì)南市2022年中考英語(yǔ)情景運(yùn)用拔高練習(xí)(Word版含答案)
- 護(hù)理查房-糖尿病足 PPT課件
- 強(qiáng)力夯實(shí)加固地基質(zhì)量通病防治
- (高清正版)T-CAGHP 015—2018地質(zhì)災(zāi)害治理工程監(jiān)理預(yù)算標(biāo)準(zhǔn)(試行)
- Q∕GDW 12083-2021 輸變電設(shè)備物聯(lián)網(wǎng)無(wú)線節(jié)點(diǎn)設(shè)備技術(shù)規(guī)范
- 公司物流倉(cāng)儲(chǔ)規(guī)劃方案及建議書(shū)
- 智能掃地機(jī)器人畢業(yè)設(shè)計(jì)
- 佳能EOS7D數(shù)碼單反相機(jī)說(shuō)明書(shū)
- 大型焰火燃放活動(dòng)方案審批表
評(píng)論
0/150
提交評(píng)論