版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 軟件課程設(shè)計(jì)報(bào)告</b></p><p><b> ——C語(yǔ)言</b></p><p> 班 級(jí): </p><p> 姓 名: </p><p> 學(xué) 號(hào):
2、 </p><p> 指導(dǎo)教師: </p><p> 日 期: 年 月 日</p><p><b> 目 錄</b></p><p><b> 1設(shè)計(jì)內(nèi)容1</b></p><p> 2應(yīng)用程序總
3、體分析與設(shè)計(jì)1</p><p> 3應(yīng)用程序各功能模塊分析與設(shè)計(jì)2</p><p><b> 3.1功能模塊2</b></p><p> 3.1.1服務(wù)器模塊2</p><p> 3.1.2客戶端模塊2</p><p> 3.2模塊流程圖4</p><p
4、><b> 4程序測(cè)試6</b></p><p><b> 4.1測(cè)試過(guò)程6</b></p><p> 4.1.1 VS 2010截圖6</p><p><b> 4.2測(cè)試結(jié)果7</b></p><p> 4.2.1服務(wù)器端截圖7</p>
5、<p> 4.2.2客戶器端截圖7</p><p><b> 5程序文檔8</b></p><p><b> 5.1使用說(shuō)明8</b></p><p><b> 5.2程序說(shuō)明8</b></p><p><b> 6 程序源代碼8&l
6、t;/b></p><p><b> 1設(shè)計(jì)內(nèi)容</b></p><p> 通過(guò)C語(yǔ)言程序編程實(shí)現(xiàn)一個(gè)局域網(wǎng)聊天程序,包括服務(wù)器端程序和客戶端程序,程序能夠?qū)崿F(xiàn)兩臺(tái)主機(jī)或多臺(tái)主機(jī)間的基本通信和文件傳輸。</p><p> 2應(yīng)用程序總體分析與設(shè)計(jì)</p><p><b> 編譯預(yù)處理命令</
7、b></p><p> #include <Winsock.h> </p><p> #include <stdio.h></p><p> #pragma comment (lib,"wsock32.lib") </p><p> 該應(yīng)用程序中使用的基本W(wǎng)insock函數(shù)有:<
8、;/p><p> WSAStartup,socket,bind,listen,accept,connect,shutdown和closesocket等,使用數(shù)據(jù)傳輸函數(shù)有send和recv。</p><p> 服務(wù)器程序的步驟如下:</p><p> 初始化以及創(chuàng)建套接字,由WSAStartup()和socket()函數(shù)完成。</p><p&g
9、t; 要將指定協(xié)議的套接字綁定到本地的IP地址和端口號(hào)。這個(gè)過(guò)程通過(guò)bind()函數(shù)來(lái)完成。</p><p> 服務(wù)器處于監(jiān)聽(tīng)狀態(tài),等待客戶端連接,以便為它們的請(qǐng)求提供服務(wù)。服務(wù)進(jìn)程必須在所綁定的名字上進(jìn)行監(jiān)聽(tīng)。因此需要把套接字置為監(jiān)聽(tīng)模式。通過(guò)listen()函數(shù)來(lái)實(shí)現(xiàn)。</p><p> 服務(wù)器程序調(diào)用函數(shù)accept準(zhǔn)備接受來(lái)自客戶端的連接。如果有一個(gè)客戶端這時(shí)用connect
10、()函數(shù)試圖建立連接,服務(wù)器端就可以接受連接。</p><p> 建立連接后,服務(wù)器端和客戶端之間就可以使用send()和recv()函數(shù)進(jìn)行通信。對(duì)輸入和接收到的信息進(jìn)行甄別,如果收到“SendFile”,則調(diào)用接收文件模塊,進(jìn)入接收文件狀態(tài);若在鍵盤(pán)輸入“SendFile”,則調(diào)用發(fā)送文件模塊,進(jìn)入發(fā)送文件狀態(tài)。否則,進(jìn)程將按照普通信息進(jìn)行收發(fā)對(duì)話。</p><p> ?。ㄟ@里需要說(shuō)
11、明的是,默認(rèn)情況下recv()函數(shù)處于阻塞模式,在接收數(shù)據(jù)前,程序?qū)⒉幌蛳聢?zhí)行。)</p><p> 在控制臺(tái)應(yīng)用窗口中,程序只能依次執(zhí)行語(yǔ)句,服務(wù)器和客戶端在收到信息后,可進(jìn)行回復(fù)(輸入回復(fù)信息,并按回車鍵發(fā)送),或者不回復(fù)(按回車鍵以接收下一條信息)。</p><p> 客戶端程序的步驟如下:</p><p> 輸入服務(wù)器IP,存放在servIP[]。&l
12、t;/p><p> 初始化以及創(chuàng)建套接字,由WSAStartup和socket函數(shù)完成。</p><p> 呼叫服務(wù)器,請(qǐng)求連接,構(gòu)造int CallServer()函數(shù),其中調(diào)用了connect()函數(shù)。</p><p> 建立連接后,服務(wù)器端和客戶端之間就可以使用send和recv函數(shù)進(jìn)行通信。對(duì)輸入和接收到的信息進(jìn)行甄別,如果收到“SendFile”,則調(diào)用
13、接收文件模塊,進(jìn)入接收文件狀態(tài);若在鍵盤(pán)輸入“SendFile”,則調(diào)用發(fā)送文件模塊,進(jìn)入發(fā)送文件狀態(tài)。否則,進(jìn)程將按照普通信息進(jìn)行收發(fā)對(duì)話。</p><p> 3應(yīng)用程序各功能模塊分析與設(shè)計(jì)</p><p><b> 3.1功能模塊</b></p><p> 3.1.1服務(wù)器模塊</p><p><b>
14、; 套接口建立模塊</b></p><p> 打開(kāi)Winsock——WSAStartup</p><p> 應(yīng)用程序或DLL只能在一次成功的WSAStartup()調(diào)用后才能進(jìn)一步調(diào)用其它的Windows Sockets API 函數(shù)。</p><p> 創(chuàng)建套接口——socket()</p><p> 服務(wù)器在使用套接
15、口通信前,必須要擁有一個(gè)套接口。使用socket()函數(shù)創(chuàng)建套接口sock. 三個(gè)參數(shù)分別為:AF_INET, SOCK_STREAM, 0。</p><p> 指定本地地址——bind()</p><p> Bind() 函數(shù)通過(guò)給套接口sock 分配一個(gè)本地名字來(lái)為套接口建立本地捆綁,即把一個(gè)套即可與一個(gè)主機(jī)地址和端口號(hào)聯(lián)系起來(lái)。</p><p><b
16、> 接收文件模塊</b></p><p> 定義結(jié)構(gòu)體——struct Filedata DataPacket(),</p><p> 用于存放文件的文件名、數(shù)據(jù)和文件大小。</p><p> 構(gòu)造寫(xiě)文件函數(shù)——DWORD Writefile(char *fname,char *fdata,int flen)</p><
17、p> 將收到的數(shù)據(jù)寫(xiě)入文件。fname:文件名字指針, fdata:文件數(shù)據(jù)指針, </p><p> flen:文件大小。</p><p><b> 發(fā)送文件模塊</b></p><p> 讀文件函數(shù)——DWORD Readfile(char *fname)</p><p> 讀取鍵盤(pán)輸入的路徑所指定的
18、文件,fname:文件名字指針。</p><p> 構(gòu)造發(fā)送文件函數(shù)——DWORD SendFile(struct Filedata Packet)</p><p> 將文件發(fā)送到客戶端,其中要使用 send() 函數(shù)。 </p><p> 信息交換模塊——void CommunicateWithClient()</p><p>
19、 監(jiān)聽(tīng)連接——listen()</p><p> 指示套接口sock 進(jìn)入監(jiān)聽(tīng)連接請(qǐng)求的狀態(tài)以及接收由客戶端發(fā)出的連接請(qǐng)求。接收連接時(shí)使用套接口sock1.</p><p> 對(duì)客戶端發(fā)送的信息進(jìn)行處理,若收到”SendFile”,則啟用接收文件模塊;否則按照一般信息處理。</p><p> 發(fā)送信息或文件,若輸入”SendFile”,則啟用發(fā)送文件模塊,讀
20、取并向客戶端發(fā)送文件;否則按照一般信息發(fā)送給客戶端。</p><p><b> 客戶端模塊</b></p><p> 套接口建立和連接模塊</p><p> 打開(kāi)Winsock——WSAStartup</p><p> 應(yīng)用程序或DLL只能在一次成功的WSAStartup()調(diào)用后才能進(jìn)一步調(diào)用其它的Window
21、s Sockets API 函數(shù)。</p><p> 創(chuàng)建套接口——socket()</p><p> 服務(wù)器在使用套接口通信前,必須要擁有一個(gè)套接口。使用socket()函數(shù)創(chuàng)建套接口sock. 三個(gè)參數(shù)分別為:AF_INET, SOCK_STREAM, 0。</p><p> 請(qǐng)求連接——connect()</p><p> 調(diào)用
22、connect()函數(shù),提出與一個(gè)服務(wù)器建立連接的請(qǐng)求,如果服務(wù)器接受請(qǐng)求,就可以在服務(wù)器端的遠(yuǎn)程套接口與客戶端的本地套接口之間建立一條連接。</p><p><b> 接收文件模塊</b></p><p> 定義結(jié)構(gòu)體——struct Filedata DataPacket(),</p><p> 用于存放文件的文件名、數(shù)據(jù)和文件大小。
23、</p><p> 構(gòu)造寫(xiě)文件函數(shù)——DWORD Writefile(char *fname,char *fdata,int flen)</p><p> 將收到的數(shù)據(jù)寫(xiě)入文件。fname:文件名字指針, fdata:文件數(shù)據(jù)指針, </p><p> flen:文件大小。</p><p> 構(gòu)造文件接收函數(shù)——void RecvFi
24、le()</p><p> 在RecvFile()函數(shù)中,當(dāng)接收完數(shù)據(jù)后,對(duì)Writefile()函數(shù)進(jìn)行調(diào)研,將數(shù)據(jù)寫(xiě)入文件中。</p><p><b> 發(fā)送文件模塊</b></p><p> 讀文件函數(shù)——DWORD Readfile(char *fname)</p><p> 讀取鍵盤(pán)輸入的路徑所指定的文
25、件,fname:文件名字指針。</p><p> 構(gòu)造發(fā)送文件函數(shù)——DWORD SendFile(struct Filedata Packet)</p><p> 將文件發(fā)送到客戶端,其中要使用 send() 函數(shù)。 </p><p> 信息交換模塊——void CommunicateWithClient()</p><p>
26、 監(jiān)聽(tīng)連接——listen()</p><p> 指示套接口sock 進(jìn)入監(jiān)聽(tīng)連接請(qǐng)求的狀態(tài)以及接收由客戶端發(fā)出的連接請(qǐng)求。接收連接時(shí)使用套接口sock1.</p><p> 對(duì)客戶端發(fā)送的信息進(jìn)行處理,若收到”SendFile”,則啟用接收文件模塊;否則按照一般信息處理。</p><p> 發(fā)送信息或文件,若輸入”SendFile”,則啟用發(fā)送文件模塊,讀取
27、并向客戶端發(fā)送文件;否則按照一般信息發(fā)送給客戶端。</p><p><b> 3.2模塊流程圖</b></p><p><b> 3.3程序結(jié)構(gòu)圖</b></p><p><b> 4程序測(cè)試</b></p><p><b> 4.1測(cè)試過(guò)程</b>
28、;</p><p> 4.1.1 VS 2010截圖</p><p><b> 服務(wù)器端 </b></p><p><b> 客戶端 </b></p><p><b> 4.2測(cè)試結(jié)果</b></p><p> 4.2.1服務(wù)器端截圖</
29、p><p> 4.2.2客戶器端截圖</p><p><b> 5程序文檔</b></p><p><b> 5.1使用說(shuō)明</b></p><p> 運(yùn)行程序,在客戶端窗口輸入服務(wù)器IP,待連接成功后,由客戶端率先向服務(wù)器發(fā)送文字信息(按回車鍵結(jié)束輸入并發(fā)送),服務(wù)器收到信息后可對(duì)客戶端信息進(jìn)
30、行回復(fù),若不回復(fù),則需按回車鍵進(jìn)入接收下一條信息的狀態(tài)。</p><p> 在服務(wù)器(或客戶端)輸入“SendFile”命令后,服務(wù)器(或客戶端)進(jìn)入發(fā)文件狀態(tài),同時(shí)提醒客戶端(或服務(wù)器)進(jìn)入接收文件狀態(tài)。在服務(wù)器(或客戶端)寫(xiě)入文件路徑,按回車就可發(fā)送到客戶端(或服務(wù)器)。</p><p><b> 5.2程序說(shuō)明</b></p><p>
31、; 本程序有兩大部分構(gòu)成,包括服務(wù)器端程序和客戶端程序。服務(wù)器端包含的模塊有套接口建立模塊、文件發(fā)送模塊、文件接收模塊、信息交換模塊;客戶端包含的模塊有套接口建立和連接模塊、文件發(fā)送模塊、文件接收模塊、信息交換模塊。</p><p><b> 服務(wù)器端</b></p><p> 套接口建立模塊用于加載套接字庫(kù),初始化和創(chuàng)建流式套接字,綁定套接字。</p&g
32、t;<p> 接收文件模塊用來(lái)實(shí)現(xiàn)文件的接收。</p><p> 發(fā)送文件模塊用于實(shí)現(xiàn)向客戶端發(fā)送文件。</p><p> 信息交換模塊中調(diào)用listen()函數(shù)和accept()函數(shù),與客戶端連接成功后,會(huì)對(duì)收到和發(fā)送的信息進(jìn)行甄別,如果收到“SendFile”命令,則調(diào)用接收文件函數(shù),如果輸入“SendFile”命令,則調(diào)用發(fā)送文件函數(shù)。</p>&l
33、t;p><b> 客戶端</b></p><p> 套接口建立和接收模塊用于加載套接字庫(kù),初始化和創(chuàng)建流式套接字,綁定套接字,和服務(wù)器進(jìn)行連接。</p><p> 接收文件模塊用來(lái)實(shí)現(xiàn)文件的接收。</p><p> 發(fā)送文件模塊用于實(shí)現(xiàn)向客戶端發(fā)送文件。</p><p> 第(一)步成功與服務(wù)器建立連接后
34、,在信息交換模塊中可以與服務(wù)器進(jìn)行信息傳遞。該模塊會(huì)對(duì)收發(fā)的信息進(jìn)行甄別,如果收到“SendFile”命令,則調(diào)用接收文件函數(shù),如果輸入“SendFile”命令,則調(diào)用發(fā)送文件函數(shù)。</p><p><b> 6 程序源代碼</b></p><p><b> //服務(wù)器端程序</b></p><p> #includ
35、e <Winsock.h> //使用版本1.1,若用版本2則使用“Winsock2.h”</p><p> #include <windows.h> //創(chuàng)建一個(gè)Windows.console程序所必須的頭文件</p><p> #include <stdio.h></p><p> #pragma comment (lib
36、,"wsock32.lib") //制定連接的庫(kù)文件。版本W(wǎng)insock 1.1使用wsock32.lib,版本W(wǎng)insock 2,使用ws2_32.lib</p><p> #define RECV_PORT 2000</p><p> //*******************************************套接口建立模塊***********
37、*****************************//</p><p> SOCKET sock,sock1; //sock 監(jiān)聽(tīng), sock1傳送數(shù)據(jù)</p><p> struct sockaddr_in ServerAddr;</p><p> struct sockaddr_in ClientAddr;</p><p>
38、 int Addrlen;</p><p> #define MAX_FILESIZE 100*1024 //限制文件最大為100K</p><p> void StartSock()</p><p><b> {</b></p><p> WSADATA WSAData;</p>
39、<p> if (WSAStartup(MAKEWORD(2,2),&WSAData)!=0) //檢查版本,初始化套接字</p><p><b> {</b></p><p> printf("sock init fail!\n");</p><p><b> }</b>
40、</p><p><b> }</b></p><p> void CreateSocket()</p><p><b> {</b></p><p> sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建套接字,AF_INET表示使用互聯(lián)網(wǎng)協(xié)議(IP)地址,SO
41、CK_STREAM創(chuàng)建流式套接口</p><p> if (sock==SOCKET_ERROR)</p><p><b> {</b></p><p> printf("sock create fail !\n");</p><p> WSACleanup();</p><
42、;p><b> }</b></p><p> ServerAddr.sin_family=AF_INET; //填充服務(wù)器地址及端口號(hào)</p><p> ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); //htonl()函數(shù)把32位主機(jī)字節(jié)順序的IP地址轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)順序</p><p>
43、; ServerAddr.sin_port=htons(RECV_PORT); //htons()函數(shù)把14位主機(jī)字節(jié)順序的端口號(hào)轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)順序</p><p> if (bind(sock,(LPSOCKADDR) & ServerAddr, sizeof(ServerAddr))==SOCKET_ERROR) //綁定套接字</p><p><
44、b> {</b></p><p> printf("bind is the error");</p><p><b> }</b></p><p><b> }</b></p><p> //******************************
45、*********************************************************************//</p><p> //*******************************************接收文件模塊****************************************//</p><p> struct Fil
46、edata //定義Filedata結(jié)構(gòu)體,變量為DataPacket</p><p><b> {</b></p><p> char ffname[30]; //ffname數(shù)組用于存放數(shù)據(jù)文件名,最長(zhǎng)為30個(gè)字符</p><p> char ffdata[MAX_FILESI
47、ZE]; //ffdata數(shù)組存放文件數(shù)據(jù),文件大小最大為,MAX_FILESIZE</p><p><b> int len;</b></p><p> }DataPacket;</p><p> DWORD Writefile(char *fname,char *fdata,int flen) //寫(xiě)文件函數(shù),將將接收到的數(shù)
48、據(jù)寫(xiě)入文件。fname:文件名字指針, fdata:文件數(shù)據(jù)指針, flen:文件大小</p><p><b> {</b></p><p><b> int i;</b></p><p> FILE *fp; //定義FILE類型的文件指針變量 *fp,系統(tǒng)可以通過(guò)文件指針變量fp找到該文件的信
49、息,并通過(guò)這些信息訪問(wèn)該文件</p><p> fp=fopen(fname,"w"); //以只寫(xiě)方式打開(kāi)一個(gè)新文本文件,若文件已經(jīng)存在,則打開(kāi)是清除原內(nèi)容</p><p> if (fp==NULL) //檢查打開(kāi)fname指向的文件操作是否成功</p><p><b> { </b><
50、/p><p> printf("cannot open this file\n");</p><p><b> }</b></p><p><b> i=0;</b></p><p> for (i=0;i<flen;i++)</p><p>&
51、lt;b> {</b></p><p> fputc(fdata[i],fp); //調(diào)用文件的字符輸入函數(shù)fputc(),將文本數(shù)據(jù)逐個(gè)字節(jié)寫(xiě)入fp所指向的文件,若調(diào)用失敗,則返回EOF,其值為-1</p><p><b> }</b></p><p> fclose(fp); //寫(xiě)入完成后記得關(guān)閉文件
52、</p><p> return (1);</p><p><b> }</b></p><p> void RecvFile() //接收文件函數(shù)</p><p><b> {</b></p><p><b> for (;;)</b>&
53、lt;/p><p><b> {</b></p><p> memset(DataPacket.ffname,0,30);</p><p> memset(DataPacket.ffdata,0,MAX_FILESIZE);</p><p> DataPacket.len=0;</p><p>
54、; if (recv(sock1,(char *)&DataPacket,sizeof(DataPacket),0)<=0) //接收數(shù)據(jù)</p><p><b> {</b></p><p><b> break;</b></p><p><b> }</b></p&
55、gt;<p> Writefile(DataPacket.ffname ,DataPacket.ffdata,DataPacket.len ); // 寫(xiě)文件,調(diào)用Writefile函數(shù),將接收到的數(shù)據(jù)寫(xiě)入文件</p><p> printf("Has receive file: %s,length is %d",DataPacket.ffname ,DataPacket
56、.len );</p><p> printf("\n");</p><p> break; //跳出循環(huán)</p><p><b> }</b></p><p><b> }</b></p><p> //******************
57、*********************************************************************************//</p><p> //*******************************************發(fā)送文件模塊****************************************//</p><p>
58、 DWORD Readfile(char *fname) //讀文件函數(shù),fname:文件名字指針 </p><p><b> {</b></p><p> FILE *fp; //定義FILE類型的文件指針變量 *fp,系統(tǒng)可以通過(guò)文件指針變量fp找到該文件的信息,并通過(guò)這些信息訪問(wèn)該文件</p><p><b&
59、gt; int i;</b></p><p> int Filesize; //Filesize:文件大小</p><p><b> char c;</b></p><p> int count,total=0; //count變量用于存放要傳送文件的數(shù)據(jù)項(xiàng)</p><p> char bu
60、ffer[100];</p><p> char Senddata[MAX_FILESIZE]; //Senddata數(shù)組用于發(fā)送數(shù)據(jù),文件大小最大為,MAX_FILESIZE</p><p> fp=fopen(fname,"r"); //以只讀方式打開(kāi)一個(gè)文件</p><p> if (fp==NULL) //檢查
61、打開(kāi)fname指向的文件操作是否成功</p><p><b> { </b></p><p> printf("cannot open this file\n");</p><p> return (0);</p><p><b> }</b></p>&l
62、t;p><b> i=0;</b></p><p> Filesize=0; //將文件大小置0</p><p> memset(Senddata,0,MAX_FILESIZE); //清空Senddata數(shù)組</p><p> while(! feof(fp)) //調(diào)用文件結(jié)束測(cè)試函數(shù)feof(),feof()功能
63、:測(cè)試fp所指向的文件是否已經(jīng)讀到文件尾部。若該文件沒(méi)有結(jié)束,則返回0.否知返回非0</p><p> //當(dāng)未讀到文件尾部是,則繼續(xù)讀取數(shù)據(jù)</p><p><b> {</b></p><p> count = fread(buffer,sizeof(char),100,fp); //調(diào)用fread()函數(shù),從文件指針fp指向的
64、文件中,讀取100個(gè)數(shù)據(jù)項(xiàng),存放到字符串?dāng)?shù)組buffer中</p><p> //若fread()函數(shù)調(diào)用成功,則返回實(shí)際讀取的數(shù)據(jù)項(xiàng)數(shù),存于變量count中,若文件結(jié)束或調(diào)用失敗,則返回0</p><p> if (ferror(fp)) //調(diào)用ferror()函數(shù),檢測(cè)文件讀寫(xiě)是否出錯(cuò),若出錯(cuò)則返回1,提示“Read File error”</p><
65、;p><b> {</b></p><p> printf("Read File error");</p><p><b> break;</b></p><p><b> }</b></p><p> Filesize += count;
66、 //計(jì)算文件總大小</p><p> if (Filesize>MAX_FILESIZE) //如果文件大于32KB,提示出錯(cuò)信息</p><p><b> {</b></p><p> printf("This File is too big\n");</p><p> fclos
67、e(fp);</p><p> return (0);</p><p><b> }</b></p><p> memcpy(&Senddata[i],buffer,count); //字符串拷貝</p><p><b> i+=count;</b></p><
68、p><b> }</b></p><p> fclose(fp); //關(guān)閉文件</p><p> Senddata[i]='\0'; //字符串以\0結(jié)束</p><p> strcpy(DataPacket.ffname ,fname);</p><p> memcpy(DataP
69、acket.ffdata ,Senddata,Filesize);</p><p> DataPacket.len = Filesize;</p><p> printf("%s %d\n",DataPacket.ffname ,DataPacket.len );</p><p> return (1);</p><p&
70、gt;<b> }</b></p><p> DWORD SendFile(struct Filedata Packet) //發(fā)送文件數(shù)據(jù)</p><p><b> {</b></p><p> int length;</p><p> length = send(sock,(char
71、 *)&Packet,sizeof(DataPacket),0); //調(diào)用send()函數(shù),發(fā)送數(shù)據(jù)</p><p> if (length<=0)</p><p><b> {</b></p><p> printf("send File error!\n");</p><p&g
72、t; closesocket(sock);</p><p> WSACleanup();</p><p> return (-1);</p><p><b> }</b></p><p> return (1);</p><p><b> }</b></p&
73、gt;<p> //***************************************************************************************************//</p><p> //*********************************************信息交換模塊*************************
74、*****************//</p><p> void CommunicateWithClient()</p><p><b> {</b></p><p> char recvBuffer[80],sendBuffer[80];</p><p> Addrlen=sizeof(struct sock
75、addr_in);</p><p> if (listen(sock,10)!=0) //設(shè)置本地套接字為監(jiān)聽(tīng)模式,正在等待連接的最大隊(duì)列長(zhǎng)度為10</p><p><b> {</b></p><p> printf("listen error");</p><p>
76、;<b> }</b></p><p> else printf("Listening....\n");</p><p><b> for (;;)</b></p><p><b> {</b></p><p> sock1=accept(sock
77、,(struct sockaddr FAR*) & ClientAddr,&Addrlen); // 接受連接</p><p> printf("Connect is OK!\n");</p><p><b> for (;;) </b></p><p> {
78、 </p><p> memset(recvBuffer,0,80); //用memset函數(shù)將recvBuffer緩存清零</p><p> memset(sendBuffer,0,80); //用memset函數(shù)將sendBuffer緩存清零</p><p
79、> //接收信息和文件**********當(dāng)收到"SendFile"時(shí),啟動(dòng)接收文件程序******************//</p><p> recv(sock1,recvBuffer,80,0);</p><p> while (!strcmp(recvBuffer,"SendFile")) //如果收到"Sen
80、dFile",則表明客戶端要向服務(wù)器發(fā)送文件,服務(wù)器進(jìn)入接收文件狀態(tài) </p><p><b> {</b></p><p> printf("準(zhǔn)備接收文件,請(qǐng)從客戶端輸寫(xiě)入要傳送文件的文件名\n");</p><p> //**************調(diào)用接收文件函數(shù)******************
81、************//</p><p> RecvFile();</p><p> memset(recvBuffer,0,80);</p><p><b> continue;</b></p><p><b> }</b></p><p><b>
82、 {</b></p><p> printf("收到的信息: %s\n",recvBuffer); //將接收到的數(shù)據(jù)打印出來(lái)</p><p> memset(recvBuffer,0,80); </p><p> printf("請(qǐng)輸入回復(fù)的信息,按回車發(fā)送(若無(wú)需回復(fù),請(qǐng)按回車以便接收下一條信息):
83、\n");</p><p><b> }</b></p><p> //發(fā)送信息和文件**********當(dāng)輸入"SendFile"時(shí),啟動(dòng)發(fā)送文件程序******************//</p><p> fflush(stdin);</p><p> gets(sendBuf
84、fer); //將要發(fā)送的信息存在sendBuffer 數(shù)組中 </p><p> while (!strcmp(sendBuffer,"SendFile")) //如果寫(xiě)入"SendFile",則表明服務(wù)器端要向客戶端發(fā)送文件,服務(wù)器進(jìn)入發(fā)送文件狀態(tài)</p><p><b> {</b></p>
85、<p> //****************調(diào)用發(fā)送文件函數(shù)*********************************//</p><p> char sendfilename[30]; //sendfilename:發(fā)送的文件名,不超過(guò)30個(gè)字節(jié)</p><p> send(sock1, sendBuffer, 80, 0); //向客戶端提示服
86、務(wù)器將給它發(fā)送文件,讓客戶端做好接收準(zhǔn)備</p><p> printf("正準(zhǔn)備發(fā)送文件,請(qǐng)輸入文件名\n");</p><p> gets(sendfilename); //給sendfilename賦值,讀取發(fā)送的文件的路徑。注意:不能用scanf()函數(shù),具體原因現(xiàn)在不明</p><p> if (strcmp(sen
87、dfilename,"exit")==0)</p><p><b> break;</b></p><p> Readfile(sendfilename); //調(diào)用ReadFile函數(shù)讀取sendfilename文件</p><p> SendFile(DataPacket); //調(diào)用SendFile函
88、數(shù)發(fā)送sendfilename文件</p><p> memset(sendBuffer,0,80); </p><p><b> continue;</b></p><p><b> }</b></p><p><b> {</b></p><p&
89、gt; send(sock1, sendBuffer, 80, 0);</p><p> memset(sendBuffer,0,80);</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p&g
90、t;<p> closesocket(sock1);</p><p><b> }</b></p><p> //***************************************************************************************************//</p><p
91、><b> //服務(wù)器主函數(shù)</b></p><p> void main()</p><p><b> {</b></p><p> printf("***********************************服務(wù)器端***********************************
92、\n");</p><p> StartSock();</p><p> CreateSocket();</p><p> CommunicateWithClient();</p><p><b> }</b></p><p><b> //客戶端程序</b&g
93、t;</p><p> #include <Winsock.h> //使用版本1.1,若用版本2則使用“Winsock2.h”</p><p> #include <stdio.h></p><p> #pragma comment (lib,"wsock32.lib") //制定連接的庫(kù)文件。版本W(wǎng)insock
94、1.1使用wsock32.lib,版本W(wǎng)insock 2,使用ws2_32.lib</p><p> #define RECV_PORT 2000</p><p> #define MAX_FILESIZE 100*1024 //限制文件最大為100K</p><p> char servIP[32]; //servIP用于存放服務(wù)器IP地址
95、,在控制臺(tái)中輸入服務(wù)器端IP地址</p><p> SOCKET sock;</p><p> struct sockaddr_in ServerAddr;</p><p> //********************************************套接口建立和連接模塊*************************************
96、****//</p><p> void StartSock()</p><p><b> {</b></p><p> WSADATA WSAData;</p><p> if (WSAStartup(MAKEWORD(2,2),&WSAData)!=0) //初始化套接字</p>&l
97、t;p><b> {</b></p><p> printf("sock init fail!\n");</p><p><b> }</b></p><p> ServerAddr.sin_family=AF_INET; //sin_family字段必須使
98、用AF_INET,告訴Winsock所使用的是IP地址族</p><p> ServerAddr.sin_addr.s_addr=inet_addr(servIP); //服務(wù)器端Ip地址</p><p> ServerAddr.sin_port=htons(RECV_PORT); //htons()函數(shù)把14位主機(jī)字節(jié)順序的端口號(hào)轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)順序</p&g
99、t;<p><b> }</b></p><p> void CreateSocket()</p><p><b> {</b></p><p> sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建套接字,AF_INET表示使用互聯(lián)網(wǎng)協(xié)議(IP)地址,SOCK_STREA
100、M創(chuàng)建流式套接口</p><p> if (sock==SOCKET_ERROR)</p><p><b> {</b></p><p> printf("sock create fail !\n");</p><p> WSACleanup();</p><p>&l
101、t;b> }</b></p><p><b> }</b></p><p> int CallServer() //呼叫服務(wù)器,請(qǐng)求連接</p><p><b> {</b></p><p> CreateSocket();</p><p> i
102、f (connect(sock,(struct sockaddr*)&ServerAddr,sizeof(ServerAddr))==INVALID_SOCKET)</p><p><b> {</b></p><p> printf("Connect fail!\n");</p><p> closesock
103、et(sock);</p><p> return(-1);</p><p><b> }</b></p><p><b> else</b></p><p> printf("connect OK ! \n");</p><p> return
104、 (1);</p><p><b> }</b></p><p> //***************************************************************************************************//</p><p> //*********************
105、************************文件接收模塊******************************************//</p><p> struct Filedata //定義Filedata結(jié)構(gòu)體,變量為DataPacket</p><p><b> {</b></p><p&
106、gt; char ffname[30]; //ffname數(shù)組用于存放數(shù)據(jù)文件名,最長(zhǎng)為30個(gè)字符</p><p> char ffdata[MAX_FILESIZE]; //ffdata數(shù)組存放文件數(shù)據(jù),文件大小最大為,MAX_FILESIZE</p><p><b> int len;</b></p><p&
107、gt; }DataPacket;</p><p> DWORD Writefile(char *fname,char *fdata,int flen) //寫(xiě)文件函數(shù),將將接收到的數(shù)據(jù)寫(xiě)入文件。fname:文件名字指針, fdata:文件數(shù)據(jù)指針, flen:文件大小</p><p><b> {</b></p><p><b&
108、gt; int i;</b></p><p> FILE *fp; //定義FILE類型的文件指針變量 *fp,系統(tǒng)可以通過(guò)文件指針變量fp找到該文件的信息,并通過(guò)這些信息訪問(wèn)該文件</p><p> fp=fopen(fname,"w"); //以只寫(xiě)方式打開(kāi)一個(gè)新文本文件,若文件已經(jīng)存在,則打開(kāi)是清除原內(nèi)容</p
109、><p> if (fp==NULL) //檢查打開(kāi)fname指向的文件操作是否成功</p><p><b> { </b></p><p> printf("cannot open this file\n");</p><p><b> }</b></p&
110、gt;<p><b> i=0;</b></p><p> for (i=0;i<flen;i++)</p><p><b> {</b></p><p> fputc(fdata[i],fp); //調(diào)用文件的字符輸入函數(shù)fputc(),將文本數(shù)據(jù)逐個(gè)字節(jié)寫(xiě)入fp所指向的文件,若調(diào)用失敗,
111、則返回EOF,其值為-1</p><p><b> }</b></p><p> fclose(fp); //寫(xiě)入完成后記得關(guān)閉文件</p><p> return (1);</p><p><b> }</b></p><p> void RecvFile
112、() //接收文件函數(shù)</p><p><b> {</b></p><p><b> for (;;)</b></p><p><b> {</b></p><p> memset(DataPacket.ffname,0,30);</p><p
113、> memset(DataPacket.ffdata,0,MAX_FILESIZE);</p><p> DataPacket.len=0;</p><p> if (recv(sock,(char *)&DataPacket,sizeof(DataPacket),0)<=0) //接收數(shù)據(jù)</p><p><b> {&l
114、t;/b></p><p><b> break;</b></p><p><b> }</b></p><p> Writefile(DataPacket.ffname ,DataPacket.ffdata,DataPacket.len ); // 寫(xiě)文件,調(diào)用Writefile函數(shù),將接收到的數(shù)據(jù)寫(xiě)入文
115、件</p><p> printf("Has receive file: %s,length is %d",DataPacket.ffname ,DataPacket.len );</p><p> printf("\n");</p><p> break; //跳出循環(huán)</p><p>&l
116、t;b> }</b></p><p><b> }</b></p><p> //***************************************************************************************************//</p><p> //******
117、**************************************文件發(fā)送模塊******************************************//</p><p> DWORD Readfile(char *fname) //讀文件函數(shù),fname:文件名字指針 </p><p><b> {</b></p><
118、;p> FILE *fp; //定義FILE類型的文件指針變量 *fp,系統(tǒng)可以通過(guò)文件指針變量fp找到該文件的信息,并通過(guò)這些信息訪問(wèn)該文件</p><p><b> int i;</b></p><p> int Filesize; //Filesize:文件大小</p><p> int count,tot
119、al=0; //count變量用于存放要傳送文件的數(shù)據(jù)項(xiàng)</p><p> char buffer[100];</p><p> char Senddata[MAX_FILESIZE]; //Senddata數(shù)組用于發(fā)送數(shù)據(jù),文件大小最大為,MAX_FILESIZE</p><p> fp=fopen(fname,"r");
120、 //以只讀方式打開(kāi)一個(gè)文件</p><p> if (fp==NULL) //檢查打開(kāi)fname指向的文件操作是否成功</p><p><b> { </b></p><p> printf("cannot open this file\n");</p><p> return (
121、0);</p><p><b> }</b></p><p><b> i=0;</b></p><p> Filesize=0; //將文件大小置0</p><p> memset(Senddata,0,MAX_FILESIZE); //清空Senddata數(shù)組</p>
122、<p> while(! feof(fp)) //調(diào)用文件結(jié)束測(cè)試函數(shù)feof(),feof()功能:測(cè)試fp所指向的文件是否已經(jīng)讀到文件尾部。若該文件沒(méi)有結(jié)束,則返回0.否知返回非0</p><p> //當(dāng)未讀到文件尾部是,則繼續(xù)讀取數(shù)據(jù)</p><p><b> {</b></p><p> count = fr
123、ead(buffer,sizeof(char),100,fp); //調(diào)用fread()函數(shù),從文件指針fp指向的文件中,讀取100個(gè)數(shù)據(jù)項(xiàng),存放到字符串?dāng)?shù)組buffer中</p><p> //若fread()函數(shù)調(diào)用成功,則返回實(shí)際讀取的數(shù)據(jù)項(xiàng)數(shù),存于變量count中,若文件結(jié)束或調(diào)用失敗,則返回0</p><p> if (ferror(fp)) //調(diào)用ferr
124、or()函數(shù),檢測(cè)文件讀寫(xiě)是否出錯(cuò),若出錯(cuò)則返回1,提示“Read File error”</p><p><b> {</b></p><p> printf("Read File error");</p><p><b> break;</b></p><p><
125、b> }</b></p><p> Filesize += count; //計(jì)算文件總大小</p><p> if (Filesize>MAX_FILESIZE) //如果文件大于32KB,提示出錯(cuò)信息</p><p><b> {</b></p><p> printf(&quo
126、t;This File is too big\n");</p><p> fclose(fp);</p><p> return (0);</p><p><b> }</b></p><p> memcpy(&Senddata[i],buffer,count); //字符串拷貝</p&
127、gt;<p><b> i+=count;</b></p><p><b> }</b></p><p> fclose(fp); //關(guān)閉文件</p><p> Senddata[i]='\0'; //字符串以\0結(jié)束</p><p> strcpy(D
128、ataPacket.ffname ,fname);</p><p> memcpy(DataPacket.ffdata ,Senddata,Filesize);</p><p> DataPacket.len = Filesize;</p><p> printf("%s %d\n",DataPacket.ffname ,DataPacke
129、t.len );</p><p> return (1);</p><p><b> }</b></p><p> DWORD SendFile(struct Filedata Packet) //發(fā)送文件數(shù)據(jù)</p><p><b> {</b></p><p>
溫馨提示
- 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ù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件課程設(shè)計(jì)---局域網(wǎng)聊天程序
- 局域網(wǎng)聊天程序java課程設(shè)計(jì)
- vc++面向?qū)ο笳n程設(shè)計(jì)報(bào)告---局域網(wǎng)聊天程序
- java課程設(shè)計(jì)--局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- java課程設(shè)計(jì)---局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- java課程設(shè)計(jì)---局域網(wǎng)聊天程序的設(shè)計(jì)與實(shí)現(xiàn)
- 基于java的局域網(wǎng)聊天系統(tǒng)-課程設(shè)計(jì)報(bào)告
- 基于java的局域網(wǎng)聊天系統(tǒng)-課程設(shè)計(jì)報(bào)告
- 基于java局域網(wǎng)聊天軟件
- 局域網(wǎng)畢業(yè)論文---局域網(wǎng)聊天軟件
- 課程設(shè)計(jì)--基于qt的局域網(wǎng)聊天室
- 局域網(wǎng)聊天軟件畢業(yè)論文
- 局域網(wǎng)聊天軟件-畢業(yè)論文
- java局域網(wǎng)聊天軟件大學(xué)設(shè)計(jì)好sqlserver
- java畢業(yè)論文---局域網(wǎng)聊天軟件
- 基于java局域網(wǎng)聊天程序設(shè)計(jì)與實(shí)現(xiàn)
- 基于java局域網(wǎng)聊天程序設(shè)計(jì)與實(shí)現(xiàn)
- 基于java局域網(wǎng)聊天軟件畢業(yè)論文
- 畢業(yè)設(shè)計(jì)--局域網(wǎng)聊天系統(tǒng)
- c++局域網(wǎng)聊天軟件設(shè)計(jì)與實(shí)現(xiàn)
評(píng)論
0/150
提交評(píng)論