版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
一、課程設(shè)計(jì)題目:通過套接字連接進(jìn)行一對一聊天通信二、實(shí)驗(yàn)要求:實(shí)現(xiàn)一個(gè)一對一的聊天程序。根本過程如下:效勞器首先啟動(dòng),創(chuàng)立套接字后等待客戶的連接;客戶啟動(dòng)以后,創(chuàng)立套接字,然后和效勞器建立連接;連接建立后,客戶機(jī)和效勞器可以通過建立的套接字連接進(jìn)行通信。效勞器和客戶端可以是一臺(tái)電腦的兩個(gè)進(jìn)程,也可以分別部署在兩臺(tái)電腦上。三、原理概述:套接字Socket是一種雙向的通信接口,可以通過這個(gè)端口與任何一個(gè)具有Socket端口的計(jì)算機(jī)通信,套接字是網(wǎng)絡(luò)通信的根底。Socket在Windows以句柄的形式被創(chuàng)立。使用Socket進(jìn)行網(wǎng)絡(luò)通信必須包含下面的幾種信息:雙方認(rèn)可的協(xié)議,本地主機(jī)的IP地址,本地進(jìn)程的協(xié)議端口,對方主機(jī)的IP地址,對方進(jìn)程的協(xié)議端口。Socket可分為:1數(shù)據(jù)報(bào)套接字〔DatagramSockets〕——對于在TCP/IP上實(shí)現(xiàn)的WinSock,數(shù)據(jù)報(bào)套接字使用用戶數(shù)據(jù)報(bào)協(xié)議〔UDP〕。數(shù)據(jù)報(bào)套接字提供了一種不可靠的、非連接的數(shù)據(jù)包通信方式。2流式套接字〔StreamSockets〕——流式套接字使用傳輸控制協(xié)議〔TCP〕。流式套接字可以將數(shù)據(jù)按順序無重復(fù)地發(fā)送到目的地,它提供的是一種可靠的、面向連接的數(shù)據(jù)傳輸方式。不管是對單個(gè)的數(shù)據(jù)報(bào),還是對數(shù)據(jù)包,流式套接字都提供了一種流式數(shù)據(jù)傳輸。VC++對網(wǎng)絡(luò)編程的支持有socket支持,Winlnet支持,MAPI和ISAPI支持等。其中WindowsSocketsAPI是TCP/IP網(wǎng)絡(luò)環(huán)境里,也是Internet上進(jìn)行開發(fā)最為通用的API。IP地址:IPAddress就是依照TCP/IP協(xié)議分配給本地主機(jī)的網(wǎng)絡(luò)地址,就向兩個(gè)進(jìn)程要通訊,任一進(jìn)程要知道通訊對方的位置,位置如何來確定,就用對方的IP端口號:用來標(biāo)識(shí)本地通訊進(jìn)程,方便OS提交數(shù)據(jù).就是說進(jìn)程指定了對方進(jìn)程的網(wǎng)絡(luò)IP,但這個(gè)IP只是用來標(biāo)識(shí)進(jìn)程所在的主機(jī),如何來找到運(yùn)行在這個(gè)主機(jī)的這個(gè)進(jìn)程呢,就用端口號.連接:指兩個(gè)進(jìn)程間的通訊鏈路.一個(gè)完整的網(wǎng)間進(jìn)程通信需要由兩個(gè)進(jìn)程組成,并且只能使用同一種高層協(xié)議。也就是說,不可能通信的一端用TCP協(xié)議,而另一端用UDP協(xié)議。因此一個(gè)完整的網(wǎng)間通信需要一個(gè)五元組來標(biāo)識(shí):協(xié)議,本地地址,本地端口號,遠(yuǎn)地地址,遠(yuǎn)地端口號這樣一個(gè)五元組,叫做一個(gè)相關(guān)association,即兩個(gè)協(xié)議相同的半相關(guān)才能組合成一個(gè)適宜的相關(guān),或完全指定組成一連接。在TCP/IP網(wǎng)絡(luò)應(yīng)用中,通信的兩個(gè)進(jìn)程間相互作用的主要模式是客戶/效勞器模式(Client/Servermodel),即客戶向效勞器發(fā)出效勞請求,效勞器接收到請求后,提供相應(yīng)的效勞??蛻?效勞器模式的建立基于以下兩點(diǎn):首先,建立網(wǎng)絡(luò)的起因是網(wǎng)絡(luò)中軟硬件資源、運(yùn)算能力和信息不均等,需要共享,從而造就擁有眾多資源的主機(jī)提供效勞,資源較少的客戶請求效勞這一非對等作用。其次,網(wǎng)間進(jìn)程通信完全是異步的,相互通信的進(jìn)程間既不存在父子關(guān)系,又不共享內(nèi)存緩沖區(qū),因此需要一種機(jī)制為希望通信的進(jìn)程間建立聯(lián)系,為二者的數(shù)據(jù)交換提供同步,這就是基涌紀(jì)紀(jì)戶/效勞器模式的TCP/IP。四.設(shè)計(jì)方案:設(shè)計(jì)原理圖:解決方案基于TCP連接Socket聊天程序基于該連接的聊天程序需要至少具備一個(gè)效勞器端〔Server〕和一個(gè)客戶端〔Client〕。在本程序中,一個(gè)用戶作為Server端,另一個(gè)用戶作為Client端。也就是說,作為Server端的用戶,需要首先啟動(dòng)程序,等待Client端的連接請求。當(dāng)TCP連接握手以后,雙方方可進(jìn)行交互。在本程序中Server端并不是單獨(dú)存在。它也可以向他的Client端發(fā)送消息。當(dāng)Client端與Server端握手以后,Server端需要首先發(fā)起會(huì)話;Client端在收到消息后再回復(fù)一條消息給Server端;同樣,Server端在收到消息后再回復(fù)一條消息給Client端……以此類推。五.程序編寫:Server.h代碼如下:#include<Afxwin.h>#include<stdio.h>#include<winsock2.h>#include<conio.h>#include<list>#include<iostream>usingnamespacestd;classCChatServer{public: CChatServer(); ~CChatServer(); boolIsConnected(){returnm_bIsConnected;}//返回連接狀態(tài) voidStartListenClient();//Listentoclient intSendMessagePort(stringsMessage);//向所有客戶端發(fā)消息 intRecClient(SOCKETsRecSocket);//接收客戶端數(shù)據(jù)private: boolm_bIsConnected;//true-connectedfalse-notconnected intm_iServerPort; list<SOCKET>m_vClientList;//Allsocketconnectedtoclient SOCKETm_SClient; SOCKETm_SListenClient;//socketlisteningforclientcalls};Server.cpp代碼如下:#include"server.h"CChatServerCServerObj;UINTServerRecThread(LPVOIDpParam)//接收數(shù)據(jù)的工作線程{ SOCKETsRecSocket=(SOCKET)pParam; while(1) { if(CServerObj.RecClient(sRecSocket)) break; } return0;}UINTServerListenThread(LPVOIDpParam)//監(jiān)聽端口建立連接的工作線程{ while(1) CServerObj.StartListenClient(); return0;}CChatServer::CChatServer()//對象CChatServer的構(gòu)造函數(shù){cout<<"StartingupTCPChatserver\n"; m_bIsConnected=false;WSADATAwsaData;sockaddr_inlocal;intwsaret=WSAStartup(0x101,&wsaData);//應(yīng)用程序調(diào)用的第一個(gè)WindowsSockets函數(shù).//它允許應(yīng)用程序或DLL指明WindowsSocketsAPI的版本號及獲得特定WindowsSockets實(shí)現(xiàn)的細(xì)節(jié).if(wsaret!=0){return;}local.sin_family=AF_INET;local.sin_addr.s_addr=INADDR_ANY;local.sin_port=htons((u_short)8084);m_SListenClient=socket(AF_INET,SOCK_STREAM,0);//創(chuàng)立一個(gè)套接字,返回套接字描述字if(m_SListenClient==INVALID_SOCKET){return;}if(bind(m_SListenClient,(sockaddr*)&local,sizeof(local))!=0)//把本地協(xié)議的地址賦予一個(gè)套接字{return;}if(listen(m_SListenClient,10)!=0)//監(jiān)聽該端口{return;} m_bIsConnected=true;return;}CChatServer::~CChatServer()//對象CChatServer的析構(gòu)函數(shù){closesocket(m_SListenClient);//關(guān)閉該端口WSACleanup();}voidCChatServer::StartListenClient(){sockaddr_infrom;intfromlen=sizeof(from);m_SClient=accept(m_SListenClient,(structsockaddr*)&from,&fromlen);//產(chǎn)生與客戶進(jìn)行TCP連接通信的套接字并返回已連接客戶端的協(xié)議地址 if(m_SClient!=INVALID_SOCKET) m_vClientList.push_back(m_SClient); AfxBeginThread(ServerRecThread,(void*)m_SClient);//啟動(dòng)接收線程,用m_SClient套接字與客戶端通話}intCChatServer::SendMessagePort(stringsMessage)//向各個(gè)客戶端發(fā)送效勞器數(shù)據(jù){ intiStat=0; list<SOCKET>::iteratoritl; if(m_vClientList.size()==0) return0; for(itl=m_vClientList.begin();itl!=m_vClientList.end();itl++) { iStat=send(*itl,sMessage.c_str(),sMessage.size()+1,0); if(iStat==-1) m_vClientList.remove(*itl); } if(iStat==-1) return1; return0;}intCChatServer::RecClient(SOCKETsRecSocket)//接收客戶端數(shù)據(jù)成員函數(shù){chartemp[4096]; intiStat; iStat=recv(sRecSocket,temp,4096,0); if(iStat==-1) { m_vClientList.remove(sRecSocket); return1; } else { cout<<":"<<temp<<"\n"; SendMessagePort(temp); return0; } return0;}intmain(intargc,char*argv[]){intnRetCode=0; charbuf[4096]; cout<<"Thisaplicationactasachatserver.\n"; cout<<"Messagesfromanypcwillbebroadcastedtoallconnectedpcs.\n"; cout<<"Connecttotheserverpcport8084\n";cout<<"PressONLYENTERtoquit.\n"; cout<<"=================================================\n"; if(!CServerObj.IsConnected())//判斷監(jiān)聽端口是否建立 { cout<<"\nFailedtoinitialiseserversocket"; cout<<"\nBye"; getch(); return1; } AfxBeginThread(ServerListenThread,0);//啟動(dòng)監(jiān)聽端口建立連接的工作線程 while(gets(buf)) { if(strlen(buf)==0) break; if(CServerObj.SendMessagePort(buf)) { cout<<"Probleminconnectingtoserver.Checkwhetherserverisrunning\n"; break; } } cout<<"readytoseegoodbye:"; getch();returnnRetCode;}Client.h#include<Afxwin.h>#include<stdio.h>#include<winsock2.h>#include<conio.h>#include<iostream>usingnamespacestd;classCIPMessage{public: CIPMessage(); ~CIPMessage(); voidInit(stringsIpAddress,intiPort); intSendMessagePort(stringsMessage); intRecMessagePort(); boolIsConnected(){returnm_bIsConnected;}private: boolm_bIsConnected;//true-connectedfalse-notconnected stringm_sServerIPAddress; intm_iServerPort; SOCKETconn;//socketconnectedtoserver};Client.cpp代碼如下:#include"client.h"http://GlobalMessageobjectCIPMessageMyMessObj;CIPMessage::CIPMessage()//MyMessObj構(gòu)造函數(shù){ m_bIsConnected=false;}voidCIPMessage::Init(stringsIpAddress,intiPort)//建立與效勞器端得連接{ m_sServerIPAddress=sIpAddress; m_iServerPort=iPort; structhostent*hp; unsignedintaddr; structsockaddr_inserver; WSADATAwsaData; intwsaret=WSAStartup(0x101,&wsaData);//應(yīng)用程序調(diào)用的第一個(gè)WindowsSockets函數(shù).//它允許應(yīng)用程序或DLL指明WindowsSocketsAPI的版本號及獲得特定WindowsSockets實(shí)現(xiàn)的細(xì)節(jié). if(wsaret!=0) { return; } conn=socket(AF_INET,SOCK_STREAM,0);//建立客戶端套接字 if(conn==INVALID_SOCKET) return; addr=inet_addr(m_sServerIPAddress.c_str());//轉(zhuǎn)化ip地址和端口為指定形式 hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET); if(hp==NULL) { closesocket(conn); return; } server.sin_addr.s_addr=*((unsignedlong*)hp->h_addr); server.sin_family=AF_INET; server.sin_port=htons(m_iServerPort); if(connect(conn,(structsockaddr*)&server,sizeof(server)))//向指定效勞器建立連接 { closesocket(conn); return; } m_bIsConnected=true; return;}CIPMessage::~CIPMessage()//MyMessObj析構(gòu)函數(shù){ if(m_bIsConnected) closesocket(conn);}intCIPMessage::SendMessagePort(stringsMessage)//向指定效勞器發(fā)出數(shù)據(jù){ intiStat=0; iStat=send(conn,sMessage.c_str(),sMessage.size()+1,0); if(iStat==-1) return1; return0;}intCIPMessage::RecMessagePort()//接收指定效勞器數(shù)據(jù){ characRetData[4096]; intiStat=0; iStat=recv(conn,acRetData,4096,0); if(iStat==-1) return1; cout<<"-->:"<<acRetData<<"\n"; return0;}UINTMessageRecThread(LPVOIDpParam)//接收指定效勞器數(shù)據(jù)線程{ while(1) { if(MyMessObj.RecMessagePort()) break; } return0;}intmain(intargc,char*argv[]){ charbuf[4096]; cout<<"ThisisaclientTCP/IPapplication\nConnectingtoport8084\n"; cout<<"\nPressONLYENTERtoquit"; cout<<"\n===============================================\n"; FILE*fp=fopen("server.ini","r");//獲取效勞器端套接字地址 if(fp==NULL) { cout<<"\nUnabletoopenserver.ini.PleasespecifyserverIPsddressinserver.ini"; return1;//mainfailed } stringsServerAddress; while((fgets(buf,4096,fp))!=NULL) { if(buf[0]=='#') continue; sServerAddress=buf; } fclose(fp); if(sServerAddress.size()==0) { cout<<"\nUnabletofindserverIPaddressinserver.ini"; cout<<"\nPleasesetserverIPaddress"; cout<<"\nBYEBYE:"; getch(); return0; } MyMessObj.Init(sServerAddress.c_str(),8084);//啟動(dòng)與效勞器連接 if(!MyMessObj.IsConnected()) { cout<<"\nUnabletoconnecttotheIPaddressspecifiedinserver.ini"; cout<<"\nPleasecheckserverIPaddress"; cout<<"\nreadytoseegoodbye:"; getch(); return0; } AfxBeginThread(MessageRecThread,0);//開啟接收數(shù)據(jù)線程 while(ge
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年甘肅省張掖市甘州區(qū)垃圾處理中心招聘臨聘人員筆試備考題庫及答案解析
- 2025黑龍江民族職業(yè)學(xué)院招聘14人考試備考試題及答案解析
- 2026湖南永州市市直企事業(yè)單位引進(jìn)急需緊缺專業(yè)人才206人考試參考試題及答案解析
- 2026貴州貴陽觀山湖區(qū)招聘城鎮(zhèn)公益性崗位工作人員12人考試備考試題及答案解析
- 2026貴州貴陽市投資控股集團(tuán)有限公司第一批子企業(yè)財(cái)務(wù)總監(jiān)市場化尋聘4人考試備考題庫及答案解析
- 2026重慶市人民醫(yī)院(重慶大學(xué)附屬人民醫(yī)院)招聘36人考試參考試題及答案解析
- 2025-2026學(xué)年山西金融職業(yè)學(xué)院招聘第二學(xué)期校外兼職教師7人考試參考試題及答案解析
- 2026年淄博周村區(qū)教育和體育局所屬事業(yè)單位公開招聘教師(21人)考試參考題庫及答案解析
- 2026年順義區(qū)馬坡鎮(zhèn)衛(wèi)生院公開招聘編外人員計(jì)劃備考題庫及參考答案詳解
- 2026年輝南縣消防救援大隊(duì)招聘消防文員的備考題庫及參考答案詳解
- 【MOOC】線性代數(shù)學(xué)習(xí)指導(dǎo)-同濟(jì)大學(xué) 中國大學(xué)慕課MOOC答案
- DB15-T 972-2024 醫(yī)療機(jī)構(gòu)物業(yè)管理服務(wù)規(guī)范
- 頸椎后路單開門椎管擴(kuò)大成形術(shù)的護(hù)理課件
- 新外研版(三起)三年級上冊英語全冊教學(xué)課件(2024年新版教材)
- 2024年重慶市高考思想政治試卷真題(含答案解析)
- 網(wǎng)架吊裝安全保證措施
- 某電廠660MW機(jī)組熱力系統(tǒng)與凝結(jié)水系統(tǒng)設(shè)計(jì)
- 交通基礎(chǔ)設(shè)施數(shù)字化轉(zhuǎn)型
- 《TCEC 2022102低溫環(huán)境條件下高壓電氣設(shè)備現(xiàn)場檢測實(shí)施導(dǎo)則 第1部分:紅外測溫》
- JB-T 8532-2023 脈沖噴吹類袋式除塵器
- 義務(wù)教育質(zhì)量監(jiān)測應(yīng)急專項(xiàng)預(yù)案
評論
0/150
提交評論