網(wǎng)絡(luò)程序設(shè)計linux服務(wù)器課程設(shè)計報告_第1頁
已閱讀1頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p><b>  網(wǎng)絡(luò)程序設(shè)計</b></p><p><b>  課程設(shè)計報告</b></p><p>  第1章 課程設(shè)計目的、要求</p><p><b>  1.1課程設(shè)計目的</b></p><p>  1.熟練掌握所學(xué)到的網(wǎng)絡(luò)套接字函數(shù)。</p&g

2、t;<p>  2.掌握UDP和TCP編程關(guān)鍵函數(shù)。</p><p>  3.掌握多進(jìn)程或多線程編程。</p><p>  4.掌握使用select實現(xiàn)I/O復(fù)用。</p><p>  5.掌握守護(hù)進(jìn)程的編寫。</p><p><b>  1.2實驗要求</b></p><p>  

3、1.認(rèn)真閱讀和掌握本實驗的相關(guān)的知識點。</p><p>  2.上機編寫并運行程序。</p><p><b>  1.3實驗內(nèi)容</b></p><p>  實現(xiàn)一個并發(fā)、IO復(fù)用的守護(hù)進(jìn)程時間服務(wù)器,要求當(dāng)客戶端向服務(wù)器發(fā)送“what’s time?”字符串時,服務(wù)器回應(yīng)當(dāng)時的系統(tǒng)時間字符串。</p><p><

4、;b>  1.4小組分工</b></p><p>  第2章 課程設(shè)計分析及內(nèi)容</p><p><b>  2.1所用知識點</b></p><p>  2.1.1套接字函數(shù)</p><p> ?、倏蛻舳怂煤瘮?shù):socket()函數(shù)、connect()函數(shù)、send()函數(shù)、recv()函數(shù),clo

5、se()函數(shù)。</p><p> ?、诜?wù)器端所用函數(shù):bind()函數(shù)、socket()函數(shù)、listen()函數(shù)、accept()函數(shù)、send()函數(shù)、accept()函數(shù)、recv()函數(shù)、close()函數(shù)。</p><p><b>  2.1.2守護(hù)進(jìn)程</b></p><p>  守護(hù)進(jìn)程,也就是通常說的Daemon進(jìn)程,是Lin

6、ux中的后臺服務(wù)進(jìn)程。它是一個生存期較長的進(jìn)程,通常獨立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。守護(hù)進(jìn)程常常在系統(tǒng)引導(dǎo)裝入時啟動,在系統(tǒng)關(guān)閉時終止。Linux系統(tǒng)有很多守護(hù)進(jìn)程,大多數(shù)服務(wù)都是通過守護(hù)進(jìn)程實現(xiàn)的。</p><p>  每一個從此終端開始運行的進(jìn)程都會依附于這個終端,這個終端就稱為這些進(jìn)程的控制終端,當(dāng)控制終端被關(guān)閉時,相應(yīng)的進(jìn)程都會自動關(guān)閉。但是守護(hù)進(jìn)程卻能夠突破這種限制,它從

7、被執(zhí)行開始運轉(zhuǎn),直到整個系統(tǒng)關(guān)閉時才退出。如果想讓某個進(jìn)程不因為用戶或終端或其他地變化而受到影響,那么就必須把這個進(jìn)程變成一個守護(hù)進(jìn)程。</p><p>  2.1.3 I/O復(fù)用</p><p>  I/O復(fù)用調(diào)用select或poll,并在該函數(shù)上阻塞,等待數(shù)據(jù)報套接口可讀;當(dāng)select返回可讀條件時,調(diào)用recvfrom將數(shù)據(jù)報拷貝到應(yīng)用程序緩沖區(qū)中。</p><

8、;p><b>  主要應(yīng)用:</b></p><p> ?。?)客戶程序需要同時處理交互式的輸入和服務(wù)器之間的網(wǎng)絡(luò)連接。</p><p> ?。?)客戶端需要對多個網(wǎng)絡(luò)連接作出反應(yīng)。</p><p>  (3)TCP服務(wù)器需要同時處理多個處于監(jiān)聽狀態(tài)和多個連接狀態(tài)的套接字。</p><p>  (4)服務(wù)器需要處理

9、多個網(wǎng)絡(luò)協(xié)議的套接字。</p><p> ?。?)服務(wù)器需要同時處理不同的網(wǎng)絡(luò)服務(wù)和協(xié)議。</p><p>  2.1.4 并發(fā)服務(wù)器</p><p>  不同于順序服務(wù)器,并發(fā)服務(wù)器就要能在一個時間為多個客戶端提供服務(wù)。 例如,一個聊天服務(wù)器可能服務(wù)一個特定的客戶端數(shù)小時──在停止為這個客戶端服務(wù)之前服務(wù)器不能等待, 除非是在等待一下個客戶端到來之前的間隙才能等待

10、。</p><p>  第3章 課程設(shè)計的實現(xiàn)</p><p>  3.1 程序運行步驟</p><p>  對于服務(wù)器端而言,由于它是一個守護(hù)進(jìn)程所以只要做到接收信息并且存儲在一個數(shù)組中即可而不必在前臺顯示,對于客戶端必須有信息的發(fā)送和接收。服務(wù)器端必須對來自客戶端的信息加以判斷。</p><p>  如果接收到的字符串與“what’s_

11、time?”字符串行匹配那么則返回給客戶端一個系統(tǒng)的時間信息,否則返回給客戶端“Input error”的字符串。</p><p><b>  如下圖所示:</b></p><p><b>  圖3-1連接流程圖</b></p><p>  3.2 客戶端主要函數(shù)</p><p>  3.2.1 s

12、ocket()函數(shù)</p><p>  socket()函數(shù)用于根據(jù)指定的地址族、數(shù)據(jù)類型和協(xié)議來分配一個套接口的描述字及其所用的資源。</p><p>  創(chuàng)建一個套接口,代碼如下: </p><p>  #include <winsock.h> </p><p>  SOCKET PASCAL FAR socket( int

13、af, int type, int protocol); </p><p>  Af是一個地址描述。目前僅支持AF_INET格式,也就是說ARPA Internet地址格式,Type是新套接口的類型描述,protocol:套接口所用的協(xié)議,如調(diào)用者不想指定,可用0指定,表示缺省。</p><p>  3.2.2 connect()函數(shù)</p><p>  本函數(shù)用于

14、創(chuàng)建與指定外部端口的連接。s參數(shù)指定一個未連接的數(shù)據(jù)報或流類套接口。如套接口未被捆綁,則系統(tǒng)賦給本地關(guān)聯(lián)一個唯一的值,且設(shè)置套接口為已捆綁。請注意若名字結(jié)構(gòu)中的地址域為全零的話,則connect()將返回WSAEADDRNOTAVAIL錯誤。</p><p>  返回值:若無錯誤發(fā)生,則connect()返回0。否則的話,返SOCKET_ERROR錯誤,應(yīng)用程序可通過WSAGetLastError()獲取相應(yīng)錯誤

15、代碼。</p><p>  創(chuàng)建一個連接,代碼如下:</p><p>  #include <winsock.h> //調(diào)用套接字</p><p>  int PASCAL FAR connect( SOCKET s, const struct sockaddr FAR* name,int namelen);</p><p> 

16、 s是標(biāo)識一個未連接套接口的描述字。</p><p>  Name是欲進(jìn)行連接的端口名。</p><p>  Namelen是名字長度。</p><p><b>  3.3服務(wù)端函數(shù)</b></p><p>  3.3.1 send函數(shù)和recv函數(shù)</p><p><b>  1.se

17、nd函數(shù)</b></p><p>  int send( SOCKET s,const char FAR *buf,int len,int flags ); </p><p>  不論是客戶還是服務(wù)器應(yīng)用程序都用send函數(shù)來向TCP連接的另一端發(fā)送數(shù)據(jù)。</p><p>  客戶程序一般用send函數(shù)向服務(wù)器發(fā)送請求,而服務(wù)器則通常用send函數(shù)來向

18、客戶程序發(fā)送應(yīng)答。</p><p>  第一個參數(shù)指定發(fā)送端套接字描述符。</p><p>  第二個參數(shù)指明一個存放應(yīng)用程序要發(fā)送數(shù)據(jù)的緩沖區(qū)。</p><p>  第三個參數(shù)指明實際要發(fā)送的數(shù)據(jù)的字節(jié)數(shù)。</p><p>  第四個參數(shù)一般置0。</p><p><b>  2.recv函數(shù)</b&

19、gt;</p><p>  int recv( SOCKET s,char FAR *buf,int len, int flags); </p><p>  不論是客戶還是服務(wù)器應(yīng)用程序都用recv函數(shù)從TCP連接的另一端接收數(shù)據(jù)。</p><p>  第一個參數(shù)指定接收端套接字描述符。</p><p>  第二個參數(shù)指明 一個緩沖區(qū),該

20、緩沖區(qū)用來存放recv函數(shù)接收到的數(shù)據(jù)。</p><p>  第三個參數(shù)指明buf的長度。</p><p>  第四個參數(shù)一般置0。</p><p>  3.3.2 close()函數(shù)</p><p>  close函數(shù)用于關(guān)閉套接字,并立即返回到進(jìn)程。關(guān)閉后的套接字描述符不能再接收和發(fā)送數(shù)據(jù),再不能作為函數(shù)send()或recv()的參數(shù)。

21、如果套接字描述符訪問計數(shù)在調(diào)用close后大于0(在多個進(jìn)程共享同一個套接字的情況下),則不會引發(fā)TCP終止序列(即不會發(fā)送FIN分節(jié))。</p><p>  3.3.3 select函數(shù)</p><p>  select()的機制中提供一fd_set的數(shù)據(jù)結(jié)構(gòu),實際上是一long類型的數(shù)組, 每一個數(shù)組元素都能與一打開的文件句柄(不管是Socket句柄,還是其他 文件或命名管道或設(shè)備句柄

22、)建立聯(lián)系,建立聯(lián)系的工作由程序員完成, 當(dāng)調(diào)用select()時,由內(nèi)核根據(jù)IO狀態(tài)修改fd_set的內(nèi)容,由此來通知執(zhí) 行了select()的進(jìn)程哪一Socket或文件可讀。</p><p>  3.4 創(chuàng)建守護(hù)進(jìn)程</p><p><b>  創(chuàng)建步驟:</b></p><p><b> ?、偈惯M(jìn)程在后臺運行</b>

23、</p><p> ?、诿撾x控制終端,登錄會話和進(jìn)程組(創(chuàng)建新會話)</p><p> ?、劢惯M(jìn)程重新打開控制終端</p><p>  ④關(guān)閉所有文件描述符</p><p><b> ?、莞淖儺?dāng)前工作目錄</b></p><p><b> ?、拗卦O(shè)權(quán)限掩碼</b></

24、p><p> ?、咛幚鞸IGCHLD信號</p><p><b>  心得體會</b></p><p>  經(jīng)過兩周的課程設(shè)計,我們對Linux有了更深的體會,意識到只有動手去操作才能真的掌握它。同樣也對服務(wù)器有了多重的認(rèn)識,認(rèn)識到其在生活中的重要性,和我們的生活密不可分。</p><p>  時間服務(wù)器更是重中所重,時間的

25、重要性越來越大,時間服務(wù)器作為時間的核心其重要性已經(jīng)不言而喻,且開發(fā)成本較小,用時較少,易于開發(fā)。不僅為我們以后的程序生涯打好基礎(chǔ),也能增加我們對編寫程序的興趣。</p><p>  這次之后,我們小組還算是比較默契的。沒想到這項看起來不需要多少技術(shù)的工作卻是非常需要耐心和精力,在兩周后的今天我已明白課程設(shè)計對我來說的意義,它不僅僅是讓我們把所學(xué)的理論知識與實踐相結(jié)合起來,提高自己的實際動手能力和獨立思考的能力,

26、更重要的是同學(xué)間的團結(jié),雖然我們這次花去的時間比別人多,但我相信我們得到的也會更多。</p><p>  在這次課程設(shè)計中,我們運用到了以前所學(xué)的專業(yè)課知識,比如并發(fā)服務(wù)器原理,I/O復(fù)用技術(shù),守護(hù)進(jìn)程的創(chuàng)建。正如孔子所說:“溫故而知新”,我們在開發(fā)的過程中有時會遇到問題,等到解決之后,發(fā)現(xiàn)自己知道了更多的東西,對知識點有了更深刻的理解。</p><p>  這也激發(fā)了我今后努力學(xué)習(xí)的興趣

27、,我想這將對我以后的學(xué)習(xí)產(chǎn)生積極的影響。其次,這次課程設(shè)計讓我充分認(rèn)識到團隊合作的重要性,只有分工協(xié)作才能保證整個項目的有條不絮。另外在課程設(shè)計的過程中,當(dāng)我們碰到不明白的問題時,指導(dǎo)老師總是耐心的講解,給我們的設(shè)計以極大的幫助,使我們獲益匪淺。因此非常感謝老師的教導(dǎo)。</p><p><b>  附錄一 系統(tǒng)界面 </b></p><p><b>  附錄

28、二 程序代碼</b></p><p><b>  客戶端程序:</b></p><p>  #include <stdio.h></p><p>  #include <stdlib.h></p><p>  #include <string.h></p>&

29、lt;p>  #include <unistd.h></p><p>  #include <sys/socket.h></p><p>  #include <netinet/in.h></p><p>  #include <netdb.h></p><p>  #define POR

30、T 1234</p><p>  #define MAXDATASIZE 100</p><p>  #define MAXLINE 100</p><p>  int main(int argc,char * argv[])</p><p><b>  {</b></p><p>  int

31、 fd,numbytes;</p><p>  char buf[MAXDATASIZE],sendline[MAXLINE];</p><p>  struct hostent * he;</p><p>  struct sockaddr_in server;</p><p>  if (argc != 3) {</p>

32、<p>  fprintf(stderr,"usage: %s <IP>address and myport\n", argv[0]);</p><p><b>  exit(1);</b></p><p><b>  }</b></p><p>  if((he=gethostb

33、yname(argv[1]))==NULL){</p><p>  perror("gethostbyname error.");</p><p><b>  exit(-1);</b></p><p><b>  }</b></p><p>  if((fd=socket(AF

34、_INET,SOCK_STREAM,0))==-1){</p><p>  perror("Create socket failed"); </p><p><b>  exit(1);</b></p><p><b>  }</b></p><p>  else print

35、f("Connect Success!\n");</p><p>  bzero(&server,sizeof(server));</p><p>  server.sin_family=AF_INET;</p><p>  server.sin_port=htons(PORT);</p><p>  server

36、.sin_addr=*((struct in_addr *)he->h_addr);</p><p>  if(connect(fd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1) {</p><p>  perror("Bind error.");</p><p>

37、<b>  exit(1);</b></p><p><b>  }</b></p><p>  if((numbytes=recv(fd,buf,MAXDATASIZE,0))==-1) {</p><p>  perror("recv error.");</p><p>&

38、lt;b>  exit(1);</b></p><p><b>  }</b></p><p>  buf[numbytes]='\0';</p><p>  printf("Server Message: %s\n",buf); </p><p>  close

39、(fd);</p><p><b>  }服務(wù)器端程序:</b></p><p>  #include <unistd.h></p><p>  #include <stdio.h></p><p>  #include <syslog.h></p><p>

40、  #include <signal.h></p><p>  #include <sys/types.h></p><p>  #include <sys/socket.h></p><p>  #include <sys/select.h></p><p>  include <arp

41、a/inet.h></p><p>  #define PORT 1234</p><p>  #define BACKLOG 5</p><p>  #define MAXLINE 255</p><p>  #define MAXFD 64</p><p>  void demon_init(const ch

42、ar *pname,int facility)</p><p><b>  {</b></p><p><b>  int i;</b></p><p>  pid_t pid;</p><p>  if((pid=fork())!=0)</p><p><b> 

43、 exit(0);</b></p><p><b>  setsid();</b></p><p>  signal(SIGHUP,SIG_IGN);</p><p>  if((pid=fork())!=0)</p><p><b>  exit(0);</b></p>

44、<p>  chdir("/");</p><p><b>  umask(0);</b></p><p>  for(i=0;i<MAXFD;i++)</p><p><b>  close(i);</b></p><p>  openlog(pname,LOG

45、_PID,facility);</p><p><b>  }</b></p><p>  int main(int argc,char **argv)</p><p><b>  {</b></p><p>  int listenfd,connfd;</p><p>  

46、socklen_t addrlen,len;</p><p>  struct sockaddr_in client_addr;</p><p>  struct sockaddr_in server;</p><p>  char buff[MAXLINE];</p><p>  time_t ticks;</p><p

47、>  bzero(&server,sizeof(server));</p><p>  bzero(&client_addr,sizeof(client_addr));</p><p>  server.sin_family=AF_INET;</p><p>  server.sin_port=htons(1234);</p>&

48、lt;p>  server.sin_addr.s_addr=htonl(INADDR_ANY);</p><p>  demon_init(argv[0],0);</p><p>  if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)</p><p><b>  {</b></p>

49、<p>  syslog(LOG_NOTICE|LOG_LOCAL0,"socket error");</p><p><b>  exit(-1);</b></p><p><b>  }</b></p><p>  if(bind(listenfd,(struct sockaddr *

50、)&server,sizeof(struct sockaddr))==-1)</p><p><b>  {</b></p><p>  syslog(LOG_NOTICE|LOG_LOCAL0,"socket error");</p><p><b>  exit(-1);</b></p

51、><p><b>  }</b></p><p>  if(listen(listenfd,BACKLOG)==-1)</p><p><b>  {</b></p><p><b>  exit(-1);</b></p><p><b>  }&

52、lt;/b></p><p><b>  for(;;){</b></p><p>  len=sizeof(client_addr);</p><p>  connfd=accept(listenfd,&client_addr,&len);</p><p>  ticks=time(NULL);&

53、lt;/p><p>  snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));</p><p><b>  int a;</b></p><p>  if((a=write(connfd,buff,strlen(buff)))==-1)</p><

54、p><b>  {</b></p><p>  syslog(LOG_NOTICE|LOG_LOCAL0,"write error");</p><p><b>  exit(0);</b></p><p><b>  }</b></p><p> 

55、 int fd_A[BACKLOG]; </p><p>  int conn_amount; </p><p><b>  int ret;</b></p><p>  int i,new_fd;</p><p>  fd_set fdsr;</p><p>  int maxsock;

56、</p><p>  struct timeval tv; </p><p>  conn_amount = 0; </p><p>  maxsock = listenfd;</p><p>  while (1) {</p><p>  FD_ZERO(&fdsr);</p><p&

57、gt;  FD_SET(listenfd, &fdsr);</p><p>  tv.tv_sec = 30;</p><p>  tv.tv_usec = 0;</p><p>  for (i = 0; i < BACKLOG; i++) {</p><p>  if (fd_A[i] != 0) {</p>

58、<p>  FD_SET(fd_A[i], &fdsr);</p><p><b>  }</b></p><p><b>  }</b></p><p>  ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);</p><

59、;p>  if (ret < 0) {</p><p>  perror("select");</p><p><b>  break;</b></p><p>  } else if (ret == 0) {</p><p>  printf("timeout\n")

60、;</p><p><b>  continue;</b></p><p><b>  }</b></p><p>  for (i = 0; i < conn_amount; i++) {</p><p>  if (FD_ISSET(fd_A[i], &fdsr)) {</p

61、><p>  ret = recv(fd_A[i], buff, sizeof(buff), 0);</p><p>  if (ret <= 0) { </p><p>  printf("client[%d] close\n", i);</p><p>  close(fd_A[i]);</p>&l

62、t;p>  FD_CLR(fd_A[i], &fdsr);</p><p>  fd_A[i] = 0;</p><p>  } else { </p><p>  if (ret < MAXLINE)</p><p>  memset(&buff[ret], '\0', 1);</p&g

63、t;<p>  printf("client[%d] send:%s\n", i, buff);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  if

64、(FD_ISSET(listenfd, &fdsr)) {</p><p>  new_fd = accept(listenfd, (struct sockaddr *)&client_addr, &len);</p><p>  if (new_fd <= 0) {</p><p>  perror("accept"

65、;);</p><p><b>  continue;</b></p><p><b>  }</b></p><p>  if (conn_amount < BACKLOG) {</p><p>  fd_A[conn_amount++] = new_fd;</p><p

66、>  printf("new connection client[%d] %s:%d\n", conn_amount,</p><p>  inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));</p><p>  if (new_fd > maxsock)</p><

67、p>  maxsock = new_fd;</p><p><b>  }</b></p><p><b>  else {</b></p><p>  printf("max connections arrive, exit\n");</p><p>  send(new

68、_fd, "bye", 4, 0);</p><p>  close(new_fd);</p><p><b>  break;</b></p><p><b>  }</b></p><p><b>  } </b></p><p>

69、;<b>  }</b></p><p>  for (i = 0; i < BACKLOG; i++) {</p><p>  if (fd_A[i] != 0) {</p><p>  close(fd_A[i]);</p><p><b>  }</b></p><p

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論