基于重疊模型的通信程序設(shè)計(jì)_第1頁
基于重疊模型的通信程序設(shè)計(jì)_第2頁
基于重疊模型的通信程序設(shè)計(jì)_第3頁
基于重疊模型的通信程序設(shè)計(jì)_第4頁
基于重疊模型的通信程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、集美大學(xué)計(jì)算機(jī)工程學(xué)院實(shí)驗(yàn)報(bào)告課程名稱:TCP/IP協(xié)議分析與編程班級(jí):實(shí)驗(yàn)成績(jī):實(shí)驗(yàn)項(xiàng)目名稱:基于重疊模型的通信程序設(shè)計(jì)學(xué)號(hào):上機(jī)實(shí)踐日期:2016-05-26實(shí)驗(yàn)項(xiàng)目編號(hào):10組號(hào):1上機(jī)實(shí)踐時(shí)間: 2學(xué)時(shí)一、 實(shí)驗(yàn)?zāi)康?了解基于重疊模型通信程序的編寫,編譯和執(zhí)行二、 實(shí)驗(yàn)內(nèi)容與設(shè)計(jì)思想編寫Win32程序?qū)崿F(xiàn)基于重疊模型的兩臺(tái)計(jì)算機(jī)之間的通信,要求編程實(shí)現(xiàn)服務(wù)器端與客戶端之間雙向數(shù)據(jù)傳遞??蛻舳讼蚍?wù)器端發(fā)送“請(qǐng)輸出1000以內(nèi)斐波那契數(shù)列”,服務(wù)器回應(yīng)客戶端給出結(jié)果。(斐波那契數(shù)列特征,F(xiàn)0=0,F(xiàn)1=1,F(xiàn)n=F(n-1)+F(n-2),n>=2)三、 實(shí)驗(yàn)使用環(huán)境操作系統(tǒng): M

2、icrosoft Windows XP SP2編程環(huán)境:Visual C+ 6.0四、實(shí)驗(yàn)步驟和調(diào)試過程源代碼服務(wù)器端:#include "stdafx.h"#include "initsock.h"#include <Mswsock.h>#include <stdio.h>#define BUFFER_SIZE 1024CInitSock initSock;/ 為每個(gè)套節(jié)字創(chuàng)建一個(gè)_SOCKET_OBJ對(duì)象typedef struct _SOCKET_OBJSOCKET s;/ 套節(jié)字句柄int nOutstandingOps;

3、/ 記錄此套節(jié)字上的重疊I/O數(shù)量LPFN_ACCEPTEX lpfnAcceptEx;/ 擴(kuò)展函數(shù)AcceptEx的指針(僅對(duì)監(jiān)聽套節(jié)字而言) SOCKET_OBJ, *PSOCKET_OBJ;/ 定義緩沖區(qū)對(duì)象buffer,記錄重疊I/O的所有屬性typedef struct _BUFFER_OBJOVERLAPPED ol;/ 重疊結(jié)構(gòu)char *buff;/ send/recv/AcceptEx所使用的緩沖區(qū)int nLen;/ buff的長(zhǎng)度PSOCKET_OBJ pSocket;/ 此I/O所屬的套節(jié)字對(duì)象int nOperation;/ 提交的操作類型#define OP_ACC

4、EPT1#define OP_READ2#define OP_WRITE3SOCKET sAccept;/ 用來保存AcceptEx接受的客戶套節(jié)字(僅對(duì)監(jiān)聽套節(jié)字而言)_BUFFER_OBJ *pNext; BUFFER_OBJ, *PBUFFER_OBJ;HANDLE g_eventsWSA_MAXIMUM_WAIT_EVENTS;/ I/O事件句柄數(shù)組int g_nBufferCount;/ 上數(shù)組中有效句柄數(shù)量PBUFFER_OBJ g_pBufferHead, g_pBufferTail;/ 記錄緩沖區(qū)對(duì)象組成的表的地址/ 申請(qǐng)?zhí)坠?jié)字對(duì)象和釋放套節(jié)字對(duì)象的函數(shù)PSOCKET_OBJ

5、GetSocketObj(SOCKET s)PSOCKET_OBJ pSocket = (PSOCKET_OBJ):GlobalAlloc(GPTR, sizeof(SOCKET_OBJ);if(pSocket != NULL)pSocket->s = s;return pSocket;void FreeSocketObj(PSOCKET_OBJ pSocket)if(pSocket->s != INVALID_SOCKET):closesocket(pSocket->s);:GlobalFree(pSocket);/ 申請(qǐng)_BUFFER_OBJ對(duì)象的函數(shù),每次調(diào)用重疊I/0

6、函數(shù)前需要申請(qǐng)PBUFFER_OBJ GetBufferObj(PSOCKET_OBJ pSocket, ULONG nLen)if(g_nBufferCount > WSA_MAXIMUM_WAIT_EVENTS - 1)return NULL;PBUFFER_OBJ pBuffer = (PBUFFER_OBJ):GlobalAlloc(GPTR, sizeof(BUFFER_OBJ);if(pBuffer != NULL)pBuffer->buff = (char*):GlobalAlloc(GPTR, nLen);pBuffer->ol.hEvent = :WSACr

7、eateEvent();pBuffer->pSocket = pSocket;pBuffer->sAccept = INVALID_SOCKET;/ 將新的BUFFER_OBJ添加到列表中if(g_pBufferHead = NULL)g_pBufferHead = g_pBufferTail = pBuffer;elseg_pBufferTail->pNext = pBuffer;g_pBufferTail = pBuffer;g_events+ g_nBufferCount = pBuffer->ol.hEvent;return pBuffer;/ 釋放_(tái)BUFFE

8、R_OBJ對(duì)象的函數(shù)void FreeBufferObj(PBUFFER_OBJ pBuffer)/ 從列表中移除BUFFER_OBJ對(duì)象PBUFFER_OBJ pTest = g_pBufferHead;BOOL bFind = FALSE;if(pTest = pBuffer)g_pBufferHead = g_pBufferTail = NULL;bFind = TRUE;elsewhile(pTest != NULL && pTest->pNext != pBuffer)pTest = pTest->pNext;if(pTest != NULL)pTest-

9、>pNext = pBuffer->pNext;if(pTest->pNext = NULL)g_pBufferTail = pTest;bFind = TRUE;/ 釋放它占用的內(nèi)存空間if(bFind)g_nBufferCount -;:CloseHandle(pBuffer->ol.hEvent);:GlobalFree(pBuffer->buff);:GlobalFree(pBuffer);/ 在緩沖區(qū)列表中查找_BUFFER_OBJ對(duì)象PBUFFER_OBJ FindBufferObj(HANDLE hEvent)PBUFFER_OBJ pBuffer

10、= g_pBufferHead;while(pBuffer != NULL)if(pBuffer->ol.hEvent = hEvent)break;pBuffer = pBuffer->pNext;return pBuffer;/ 更新事件句柄數(shù)組g_eventsvoid RebuildArray()PBUFFER_OBJ pBuffer = g_pBufferHead;int i = 1;while(pBuffer != NULL)g_eventsi+ = pBuffer->ol.hEvent;pBuffer = pBuffer->pNext;/ 提交接收連接的_B

11、UFFER_OBJ對(duì)象BOOL PostAccept(PBUFFER_OBJ pBuffer)PSOCKET_OBJ pSocket = pBuffer->pSocket;if(pSocket->lpfnAcceptEx != NULL)/ 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計(jì)數(shù)pBuffer->nOperation = OP_ACCEPT;pSocket->nOutstandingOps +;/ 投遞此重疊I/O DWORD dwBytes;pBuffer->sAccept = :WSASocket(AF_INET, SOCK_STREAM, 0, NUL

12、L, 0, WSA_FLAG_OVERLAPPED);BOOL b = pSocket->lpfnAcceptEx(pSocket->s, pBuffer->sAccept,pBuffer->buff, BUFFER_SIZE - (sizeof(sockaddr_in) + 16) * 2),sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &dwBytes, &pBuffer->ol);if(!b)if(:WSAGetLastError() != WSA_IO_PENDING)return

13、FALSE;return TRUE;return FALSE;/ 提交接收數(shù)據(jù)的_BUFFER_OBJ對(duì)象BOOL PostRecv(PBUFFER_OBJ pBuffer)/ 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計(jì)數(shù)pBuffer->nOperation = OP_READ;pBuffer->pSocket->nOutstandingOps +;/ 投遞此重疊I/ODWORD dwBytes;DWORD dwFlags = 0;WSABUF buf;buf.buf = pBuffer->buff;buf.len = pBuffer->nLen;if(:WSA

14、Recv(pBuffer->pSocket->s, &buf, 1, &dwBytes, &dwFlags, &pBuffer->ol, NULL) != NO_ERROR)if(:WSAGetLastError() != WSA_IO_PENDING)return FALSE;return TRUE;/ 提交發(fā)送數(shù)據(jù)的_BUFFER_OBJ對(duì)象BOOL PostSend(PBUFFER_OBJ pBuffer)/ 設(shè)置I/O類型,增加套節(jié)字上的重疊I/O計(jì)數(shù)pBuffer->nOperation = OP_WRITE;pBuffer-&

15、gt;pSocket->nOutstandingOps +;/ 投遞此重疊I/ODWORD dwBytes;DWORD dwFlags = 0;WSABUF buf;buf.buf = pBuffer->buff;buf.len = pBuffer->nLen;/計(jì)算1000以內(nèi)斐波那契數(shù)列char str100="1000以內(nèi)斐波那契數(shù)列為:"char str110;int x=0,y=1,z;for(int i=2;z<=1000;i+)z=x+y;itoa(y,str1,10);strcat(str1," ");strcat

16、(str,str1);x=y;y=z;buf.buf = str;buf.len = strlen(str);/發(fā)送數(shù)據(jù)給客戶端printf("發(fā)送數(shù)據(jù):n") ;printf("%s",str);if(:WSASend(pBuffer->pSocket->s, &buf, 1, &dwBytes, dwFlags, &pBuffer->ol, NULL) != NO_ERROR)if(:WSAGetLastError() != WSA_IO_PENDING)return FALSE;return TRUE;BO

17、OL HandleIO(PBUFFER_OBJ pBuffer)PSOCKET_OBJ pSocket = pBuffer->pSocket; / 從BUFFER_OBJ對(duì)象中提取SOCKET_OBJ對(duì)象指針,為的是方便引用pSocket->nOutstandingOps -;/ 獲取重疊操作結(jié)果DWORD dwTrans;DWORD dwFlags;BOOL bRet = :WSAGetOverlappedResult(pSocket->s, &pBuffer->ol, &dwTrans, FALSE, &dwFlags);if(!bRet)/

18、 在此套節(jié)字上有錯(cuò)誤發(fā)生,因此,關(guān)閉套節(jié)字,移除此緩沖區(qū)對(duì)象。/ 如果沒有其它拋出的I/O請(qǐng)求了,釋放此緩沖區(qū)對(duì)象,否則,等待此套節(jié)字上的其它I/O也完成if(pSocket->s != INVALID_SOCKET):closesocket(pSocket->s);pSocket->s = INVALID_SOCKET;if(pSocket->nOutstandingOps = 0)FreeSocketObj(pSocket);FreeBufferObj(pBuffer);return FALSE;/ 沒有錯(cuò)誤發(fā)生,處理已完成的I/Oswitch(pBuffer-&g

19、t;nOperation)case OP_ACCEPT:/ 接收到一個(gè)新的連接,并接收到了對(duì)方發(fā)來的第一個(gè)封包/ 為新客戶創(chuàng)建一個(gè)SOCKET_OBJ對(duì)象PSOCKET_OBJ pClient = GetSocketObj(pBuffer->sAccept);/ 為發(fā)送數(shù)據(jù)創(chuàng)建一個(gè)BUFFER_OBJ對(duì)象,這個(gè)對(duì)象會(huì)在套節(jié)字出錯(cuò)或者關(guān)閉時(shí)釋放PBUFFER_OBJ pSend = GetBufferObj(pClient, BUFFER_SIZE);if(pSend = NULL)printf(" Too much connections! n");FreeSocke

20、tObj(pClient);return FALSE;RebuildArray();/打印接收到的數(shù)據(jù) printf("接收到的數(shù)據(jù):%sn",pBuffer->buff) ; / 將數(shù)據(jù)復(fù)制到發(fā)送緩沖區(qū)pSend->nLen = dwTrans;memcpy(pSend->buff, pBuffer->buff, dwTrans);/ 投遞此發(fā)送I/O(將數(shù)據(jù)回顯給客戶)if(!PostSend(pSend)/ 萬一出錯(cuò)的話,釋放上面剛申請(qǐng)的兩個(gè)對(duì)象FreeSocketObj(pSocket);FreeBufferObj(pSend);return

21、 FALSE;/ 繼續(xù)投遞接受I/OPostAccept(pBuffer);break;case OP_READ:/ 接收數(shù)據(jù)完成if(dwTrans > 0)/ 創(chuàng)建一個(gè)緩沖區(qū),以發(fā)送數(shù)據(jù)。這里就使用原來的緩沖區(qū)PBUFFER_OBJ pSend = pBuffer;pSend->nLen = dwTrans;/ 投遞發(fā)送I/O(將數(shù)據(jù)回顯給客戶)PostSend(pSend);else/ 套節(jié)字關(guān)閉/ 必須先關(guān)閉套節(jié)字,以便在此套節(jié)字上投遞的其它I/O也返回if(pSocket->s != INVALID_SOCKET):closesocket(pSocket->s

22、);pSocket->s = INVALID_SOCKET;if(pSocket->nOutstandingOps = 0)FreeSocketObj(pSocket);FreeBufferObj(pBuffer);return FALSE;break;case OP_WRITE:/ 發(fā)送數(shù)據(jù)完成if(dwTrans > 0)/ 繼續(xù)使用這個(gè)緩沖區(qū)投遞接收數(shù)據(jù)的請(qǐng)求pBuffer->nLen = BUFFER_SIZE;PostRecv(pBuffer);else/ 套節(jié)字關(guān)閉/ 同樣,要先關(guān)閉套節(jié)字if(pSocket->s != INVALID_SOCKET)

23、:closesocket(pSocket->s);pSocket->s = INVALID_SOCKET;if(pSocket->nOutstandingOps = 0)FreeSocketObj(pSocket);FreeBufferObj(pBuffer);return FALSE;break;return TRUE;void main()/ 創(chuàng)建監(jiān)聽套節(jié)字,綁定到本地端口,進(jìn)入監(jiān)聽模式int nPort = 4567;SOCKET sListen = :WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_F

24、LAG_OVERLAPPED);SOCKADDR_IN si;si.sin_family = AF_INET;si.sin_port = :ntohs(nPort);si.sin_addr.S_un.S_addr = INADDR_ANY;:bind(sListen, (sockaddr*)&si, sizeof(si);:listen(sListen, 200);/ 為監(jiān)聽套節(jié)字創(chuàng)建一個(gè)SOCKET_OBJ對(duì)象PSOCKET_OBJ pListen = GetSocketObj(sListen);/ 加載擴(kuò)展函數(shù)AcceptExGUID GuidAcceptEx = WSAID_AC

25、CEPTEX;DWORD dwBytes;WSAIoctl(pListen->s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx),&pListen->lpfnAcceptEx, sizeof(pListen->lpfnAcceptEx), &dwBytes, NULL, NULL);/ 創(chuàng)建用來重新建立g_events數(shù)組的事件對(duì)象g_events0 = :WSACreateEvent();/ 在此可以投遞多個(gè)接受I/O請(qǐng)求for(int i=0; i&l

26、t;5; i+)PostAccept(GetBufferObj(pListen, BUFFER_SIZE);:WSASetEvent(g_events0);while(TRUE)int nIndex = :WSAWaitForMultipleEvents(g_nBufferCount + 1, g_events, FALSE, WSA_INFINITE, FALSE);if(nIndex = WSA_WAIT_FAILED)printf("WSAWaitForMultipleEvents() failed n");break;nIndex = nIndex - WSA_WA

27、IT_EVENT_0;for(int i=0; i<=nIndex; i+)int nRet = :WSAWaitForMultipleEvents(1, &g_eventsi, TRUE, 0, FALSE);if(nRet = WSA_WAIT_TIMEOUT)continue;else:WSAResetEvent(g_eventsi);/ 重新建立g_events數(shù)組if(i = 0)RebuildArray();continue;/ 處理這個(gè)I/OPBUFFER_OBJ pBuffer = FindBufferObj(g_eventsi);if(pBuffer != NU

28、LL)if(!HandleIO(pBuffer)RebuildArray();客戶端:#include <stdio.h>#include <winsock2.h>#pragma comment(lib, "WS2_32")/ 鏈接到WS2_32.libclass CInitSockpublic:CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)/ 初始化WS2_32.dllWSADATA wsaData;WORD sockVersion = MAKEWORD(minorVer, majorVer);if(:WSAStartup(sockVersion, &wsaData) != 0) return;CInitSock():WSACleanup();CInitSock theSock; /加載套接字庫int main()/ 創(chuàng)建套節(jié)字SOCKET s = :socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(s = INVALI

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論